1 Introduction

Update of explore-JULES-ES-1p0.Rmd that uses the new packages and functions

We build and test gaussian process emulators, perform a sensitivity analyis, and constrain the input space of Jules.

Andy thinks there might be mileage in analysing the atmospheric growth, which is here. /home/h01/hadaw/Research/ES_PPE/Oct20

At the moment, this vignette is hampered by the fact that emulators are failing on a few of the outputs which represent change over the historical period. The emulator is fine for predicting absolute values in the modern period.

Andy would like to see timeseries of: cVeg, cSoil and nbp, npp in GtC and GtC/yr.

1.1 Preliminaries

Load libraries, functions and data.

# Load helper functions

knitr::opts_chunk$set(fig.path = "figs/", echo = TRUE, message = FALSE, warnings = FALSE)
# load some helper functions
source('~/brazilCSSP/code/brazil_cssp/per_pft.R') # eventually, move the relevant functions
source('explore-JULES-ES-1p0_PPE_functions.R')
# Load packages

library(RColorBrewer)
library(fields)
library(MASS)
library(DiceKriging)
library(DiceEval)
library(ncdf4)
library(ncdf4.helpers)
library(readxl)

library(foreach)

library(emtools)
library(imptools)
library(viztools)
library(julesR)
# Some pallete options
yg = brewer.pal(9, "YlGn")
ryb = brewer.pal(11, "RdYlBu")
byr = rev(ryb)
rb = brewer.pal(11, "RdBu")
br = rev(rb)
blues = brewer.pal(9, 'Blues')
cbPal <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

ysec = 60*60*24*365
years <- 1850:2013

1.2 Carbon budget data

Section 2.5 in Friedlingstein et al. describes how the land carbon sink is estimated.



# Question: How closely should our model match this curve? Which output?
# (My guess is 'Total Land Carbon anomaly')
historical_carbon_budget <- read_excel('Global_Carbon_Budget_2020v1.0.xlsx', sheet = "Historical Budget", skip = 15)

par(mfrow = c(3,1))
ylim = c(-1, 6)

plot(historical_carbon_budget$Year, historical_carbon_budget$`land sink`, type = 'l', bty = 'n', ylim = ylim)

plot(historical_carbon_budget$Year, historical_carbon_budget$`land-use change emissions`, type = 'l', bty = 'n', ylim = ylim)

plot(historical_carbon_budget$Year, historical_carbon_budget$`atmospheric growth`, type = 'l', bty = 'n', ylim = ylim)

1.2.1 Jules output data location


ensloc <- '/project/carbon_ppe/JULES-ES-1p0_PPE/'
ensmember <- 'P0000/'
subdir <- 'stats/'

floc <- paste0(ensloc,ensmember,subdir)
fn <- 'JULES-ES-1p0_P0000_Annual_global.nc'

# test file
nc <- nc_open(paste0(floc,fn))

# What variables are in the file? 
varlist <- nc.get.variable.list(nc)


for(i in 1:length(varlist)){
  
  var <- varlist[i]
  print(var)
  print(ncatt_get(nc,var,"long_name")[[2]])
}

1.3 Extract a time series of an annual, globally aggregated variable


extractTimeseries <- function(nc, variable){
    dat <- ncvar_get(nc, variable)
    out <- dat
    out
}

makeTimeseriesEnsemble <- function(variable, nens = 499, nts = 164, cn = 1850:2013){
  
  # nens is number of ensemble members
  # nts length of timeseries
  # cn is colnames()
  datmat <- matrix(NA, nrow = nens, ncol = nts)
  colnames(datmat) <- cn
  
  enslist <- paste("P", formatC(0:(nens-1), width=4, flag="0"), sep="")
  floc <- paste0(ensloc,ensmember,subdir)
  
  for(i in 1:nens){
    
    vec <- rep(NA,nts)
    
    ensmember <- enslist[i] 
    
    fn <- paste0(ensloc,ensmember,'/stats/','JULES-ES-1p0_',ensmember,'_Annual_global.nc')
 
    
    try(nc <- nc_open(paste0(fn)))
    try(dat <- extractTimeseries(nc, variable))
    
    datmat[i, ] <- dat
    nc_close(nc)
  }
  datmat
}

1.4 Plot timeseries of aggregated global timeseries


par(mfrow= c(3,4), las = 1)

plotcol <- c(makeTransparent('black', 70))

ylim = range(c(npp_ens[,1], npp_ens[,164]))
matplot(years, t(npp_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'NPP', xlab = '',
        bty = 'n')

ylim = range(c(cSoil_ens[,1], cSoil_ens[,164]))
matplot(years, t(cSoil_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Soil Carbon',xlab = '',
        bty = 'n')

ylim = range(c(cVeg_ens[,1], cVeg_ens[,164]))
matplot(years, t(cVeg_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Vegetation Carbon',xlab = '',
        bty = 'n')

ylim = range(total_land_carbon_ens)
matplot(years, t(total_land_carbon_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol, 
        ylab = 'GtC', main = 'Total Land Carbon',xlab = '',
        bty = 'n')


ylim = range(lai_lnd_mean_ens)
matplot(years, t(lai_lnd_mean_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'LAI', main = 'Leaf area index',xlab = '',
        bty = 'n')

ylim = range(treeFrac_lnd_mean_ens)
matplot(years, t(treeFrac_lnd_mean_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'fraction', main = 'Tree fraction',xlab = '',
        bty = 'n')

ylim = range(shrubFrac_lnd_mean_ens)
matplot(years, t(shrubFrac_lnd_mean_ens ), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'fraction', main = 'Shrub fraction',xlab = '',
        bty = 'n')

ylim = range(baresoilFrac_lnd_mean_ens)
matplot(years, t(baresoilFrac_lnd_mean_ens ), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'fraction', main = 'bare soil fraction',xlab = '',
        bty = 'n')

ylim = c(-10, 10)
matplot(years, t(nbp_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol, 
        ylab = 'GtC', main = 'NBP', xlab = '',
        bty = 'n')
  
ylim = range(rh_lnd_sum_ens)
matplot(years, t(rh_lnd_sum_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC/year', main = 'Heterotrophic Respiration', xlab = '',
        bty = 'n')

ylim = range(fLuc_lnd_sum_ens)
matplot(years, t(fLuc_lnd_sum_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC/year', main = 'Land use change emissions', xlab = '',
        bty = 'n')

ylim = range(fHarvest_lnd_sum_ens)
matplot(years, t(fHarvest_lnd_sum_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC/year', main = 'Harvest C flux to atmosphere', xlab = '',
        bty = 'n')

NA
NA
NA
NA

npp_ens_anom <- anomalizeTSmatrix(npp_ens, 1:20)
nbp_ens_anom <- anomalizeTSmatrix(nbp_ens, 1:20)
cSoil_ens_anom <- anomalizeTSmatrix(cSoil_ens, 1:20)
cVeg_ens_anom <- anomalizeTSmatrix(cVeg_ens, 1:20)
total_land_carbon_anom <- anomalizeTSmatrix(total_land_carbon_ens, 1:20)

par(mfrow= c(1,4), las = 1)

# ylim = range(-10, 10)
#matplot(years, t(nbp_ens_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
#        ylab = 'NBP sum Anomaly', main = 'NBP Anomaly',
#        bty = 'n')

ylim = range(c(npp_ens_anom[,1], npp_ens_anom[,164]))
matplot(years, t(npp_ens_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'NPP sum Anomaly', main = 'NPP Anomaly',
        bty = 'n')

ylim = range(c(cSoil_ens_anom[,1], cSoil_ens_anom[,164]))
matplot(years, t(cSoil_ens_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Soil Carbon Anomaly',
        bty = 'n')

ylim = range(c(cVeg_ens_anom[,1], cVeg_ens_anom[,164]))
matplot(years, t(cVeg_ens_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Vegetation Carbon Anomaly',
        bty = 'n')

ylim = range(total_land_carbon_anom)
matplot(years, t(total_land_carbon_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Total Land Carbon Anomaly',
        bty = 'n')

NA
NA

1.5 Can we understand change and absolute?

1.6 Function to extract the “modern value” direct from the file (last 20 years of the timeseries)

# for each of the variables in the file, average the last 20 years as the "modern" value,
# and then place in a matrix

modernValue <- function(nc, variable, ix){
  # A basic function to read a variable and 
  # take the mean of the timeseries at locations ix
  dat <- ncvar_get(nc, variable)
  out <- mean(dat[ix])
  out
}
#144:164 is the 1993:2013
modernValue(nc = nc, variable = "npp_nlim_lnd_mean", ix = 144:164)
# apply to the test file to check it works
vec <- sapply(varlist, FUN = modernValue, nc = nc, ix = 144:164)

1.7 Loop to extract the “modern value” of a number of model outputs

# Generate ensemble numbers, mean of the last 20 years of the timeseries (1994-2013)

if (file.exists("ensemble.rdata")) {
  load("ensemble.rdata")
} else {
  
  nens = 499
  datmat <- matrix(nrow = nens, ncol = length(varlist))
  colnames(datmat) <- varlist
  
  enslist <- paste("P", formatC(0:(nens-1), width=4, flag="0"), sep="")
  floc <- paste0(ensloc,ensmember,subdir)
  
  for(i in 1:nens){
    
    vec <- rep(NA, length(varlist))
    
    ensmember <- enslist[i] 
    
    fn <- paste0(ensloc,ensmember,'/stats/','JULES-ES-1p0_',ensmember,'_Annual_global.nc')
    #print(fn)
    
    try(nc <- nc_open(paste0(fn)))
    try(vec <- sapply(varlist, FUN = modernValue, nc = nc, ix = 144:164))
    datmat[i, ] <- vec
    nc_close(nc)
  }
  
  save(nens, datmat,enslist,floc, file ="ensemble.rdata")
}

1.8 Calculate an ensemble of anomalies for all variables

For each ensemble member and each variable, calculate the change from the 20 years at the start of the run, to the twenty years at the end of the run.


extractTimeseries <- function(nc, variable){
    dat <- ncvar_get(nc, variable)
    out <- dat
    out
}

makeTimeseriesEnsemble <- function(variable, nens = 499, nts = 164, cn = 1850:2013){
  
  # nens is number of ensemble members
  # nts length of timeseries
  # cn is colnames()
  datmat <- matrix(NA, nrow = nens, ncol = nts)
  colnames(datmat) <- cn
  
  enslist <- paste("P", formatC(0:(nens-1), width=4, flag="0"), sep="")
  floc <- paste0(ensloc,ensmember,subdir)
  
  for(i in 1:nens){
    
    vec <- rep(NA,nts)
    
    ensmember <- enslist[i] 
    
    fn <- paste0(ensloc,ensmember,'/stats/','JULES-ES-1p0_',ensmember,'_Annual_global.nc')
 
    
    try(nc <- nc_open(paste0(fn)))
    try(dat <- extractTimeseries(nc, variable))
    
    datmat[i, ] <- dat
    nc_close(nc)
  }
  datmat
}
# Generate ensemble  mean of the last 20 years of the timeseries (1994-2013)

if (file.exists("anomaly_ensemble.rdata")) {
  load("anomaly_ensemble.rdata")
} else {
  
  nens = 499
  datmatAnom <- matrix(nrow = nens, ncol = length(varlist))
  colnames(datmatAnom) <- varlist
  
  enslist <- paste("P", formatC(0:(nens-1), width=4, flag="0"), sep="")
  floc <- paste0(ensloc,ensmember,subdir)
  
  for(i in 1:nens){
    
    vec <- rep(NA, length(varlist))
    
    ensmember <- enslist[i] 
    
    fn <- paste0(ensloc,ensmember,'/stats/','JULES-ES-1p0_',ensmember,'_Annual_global.nc')
    #print(fn)
    
    try(nc <- nc_open(paste0(fn)))
    try(vec <- sapply(varlist, FUN = tsAnomaly, nc = nc))
    datmatAnom[i, ] <- vec
    nc_close(nc)
  }
  
  save(nens, datmatAnom, enslist,floc, file ="anomaly_ensemble.rdata")
}

1.9 Clean data sets to “level 0”

Initial clean of data set, removing variables that don’t change, and removing NAs (models that didn’t run).


Y_nlevel0_ix <- which(is.na(datmat[,'year']))

YAnom_nlevel0_ix <- which(is.na(datmatAnom[,'year']))

# This should be true to proceed, or we'll have to start excluding the combined set.
identical(Y_nlevel0_ix, YAnom_nlevel0_ix)
[1] TRUE
# Y is the whole data set
Y <- datmat
# Y_level0 is the 'cleaned' data set, truncated to variables that change, and removing NAs
Y_level0 <- datmat[-Y_nlevel0_ix, -c(2,30,31)]
Y_nlevel0 <- datmat[Y_nlevel0_ix, -c(2, 30, 31)]


# Y is the whole data set
YAnom <- datmatAnom
# Y.level0 is the 'cleaned' data set, truncated to variables that change, and removing NAs
YAnom_level0 <- datmatAnom[-YAnom_nlevel0_ix, -c(2,30,31)]
YAnom_nlevel0 <- datmatAnom[YAnom_nlevel0_ix, -c(2,30,31)]
# load the original design and input space, normalize to [0-1]

# Load up the data
lhs_i = read.table('~/brazilCSSP/code/brazil_cssp/analyze_u-ao732/data/ES_PPE_i/lhs_u-ao732.txt', header = TRUE)
lhs_ii = read.table('~/brazilCSSP/code/brazil_cssp/analyze_u-ao732/data/ES_PPE_ii/lhs_u-ao732a.txt', header = TRUE)

toplevel_ix = 1:499

# The raw input data is a latin hypercube
lhs = rbind(lhs_i, lhs_ii)[toplevel_ix, ]
lhs_level0 <- lhs[-Y_nlevel0_ix,]

X = normalize(lhs)
colnames(X) = colnames(lhs)

X_level0 <- X[-Y_nlevel0_ix,]
X_nlevel0 <- X[Y_nlevel0_ix,]

d = ncol(X)
# lower and higher bound on the normalised matrix for visualisation
rx = rbind(rep(0,32), rep(1,32))

1.10 Where did the model fail to run?

(“probability of run failure” Could be an interesting project - logit transformation for probability of run failure? Some other ML like SVM?

There are clear run failure thresholds in the parameters rootd_ft_io and lai_max, and quite strong visual indications that a_wl_io and bio_hum_cn matter.

NEXT, histograms of failure with the LHS value


# NB, plotting the inverse of this doesn't give you much information

#simple way
par(oma = c(10,10,0,0))
#par(xpd = TRUE)
pairs(X_nlevel0, 
      xlim = c(0,1), ylim = c(0,1),
      labels = 1:d,
      col = makeTransparent('red', 150),
      gap = 0,
      pch = 20,
      xaxt ='n', yaxt = 'n',
      lower.panel = NULL)

reset()

legend('left', legend = paste(1:d, colnames(lhs)), cex = 1.2, bty = 'n')


#ynames_const <- c('nbp_lnd_sum', 'npp_nlim_lnd_sum', 'cSoil_lnd_sum', 'cVeg_lnd_sum')
#yunits_const <- c('GtC/year', 'GtC/year', 'GtC', 'GtC')
#Y_const_level1 <- Y_level1[, ynames_const]

# primary carbon cycle outputs
npp_ens <- makeTimeseriesEnsemble(variable = "npp_nlim_lnd_sum") / (1e12/ysec)
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
nbp_ens <-  makeTimeseriesEnsemble(variable = "nbp_lnd_sum") / (1e12/ysec)
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
cSoil_ens <-  makeTimeseriesEnsemble(variable = "cSoil_lnd_sum") / 1e12
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
cVeg_ens <-  makeTimeseriesEnsemble(variable = "cVeg_lnd_sum") / 1e12
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
total_land_carbon_ens <- cSoil_ens + cVeg_ens

lai_lnd_mean_ens <- makeTimeseriesEnsemble(variable = "lai_lnd_mean")
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
# fluxes
rh_lnd_sum_ens <- makeTimeseriesEnsemble(variable = "rh_lnd_sum") / (1e12/ysec)
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
fLuc_lnd_sum_ens <- makeTimeseriesEnsemble(variable = "fLuc_lnd_sum") / (1e12/ysec)
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
fHarvest_lnd_sum_ens <- makeTimeseriesEnsemble(variable = "fHarvest_lnd_sum") / (1e12/ysec)
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
# fractions
treeFrac_lnd_mean_ens <- makeTimeseriesEnsemble(variable = "treeFrac_lnd_mean")
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
shrubFrac_lnd_mean_ens <- makeTimeseriesEnsemble(variable = "shrubFrac_lnd_mean")
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
baresoilFrac_lnd_mean_ens <- makeTimeseriesEnsemble(variable = "baresoilFrac_lnd_mean")
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0069/stats/JULES-ES-1p0_P0069_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0086/stats/JULES-ES-1p0_P0086_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0144/stats/JULES-ES-1p0_P0144_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0165/stats/JULES-ES-1p0_P0165_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0168/stats/JULES-ES-1p0_P0168_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0183/stats/JULES-ES-1p0_P0183_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0185/stats/JULES-ES-1p0_P0185_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0214/stats/JULES-ES-1p0_P0214_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0216/stats/JULES-ES-1p0_P0216_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0235/stats/JULES-ES-1p0_P0235_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0238/stats/JULES-ES-1p0_P0238_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0251/stats/JULES-ES-1p0_P0251_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0259/stats/JULES-ES-1p0_P0259_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0285/stats/JULES-ES-1p0_P0285_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0357/stats/JULES-ES-1p0_P0357_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0376/stats/JULES-ES-1p0_P0376_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0387/stats/JULES-ES-1p0_P0387_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0394/stats/JULES-ES-1p0_P0394_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0405/stats/JULES-ES-1p0_P0405_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0424/stats/JULES-ES-1p0_P0424_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0455/stats/JULES-ES-1p0_P0455_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
Error in R_nc4_open: No such file or directory
Error in nc_open(paste0(fn)) : 
  Error in nc_open trying to open file /project/carbon_ppe/JULES-ES-1p0_PPE/P0457/stats/JULES-ES-1p0_P0457_Annual_global.nc
Error in R_nc4_inq_varndims: NetCDF: Not a valid ID
Error in ncvar_ndims(ncid, varid) : error returned from C call
Error in R_nc4_close: NetCDF: Not a valid ID
#c3PftFrac_lnd_mean_ens <- makeTimeseriesEnsemble(variable = "c3PftFrac_lnd_mean_ens")
#c4PftFrac_lnd_mean_ens <- makeTimeseriesEnsemble(variable = "c4PftFrac_lnd_mean_ens")

1.11 Testing Gaussian Process emulators

1.11.1 NPP as a test

First, use mean NPP as an example. How does NPP respond to each parameter? NAs are removed, but zero values are still included.

p <- ncol(X_level0)

y_level0 <- Y_level0[,'npp_nlim_lnd_sum']

par(mfrow = c(5,7), mar = c(3,1,3,1), oma = c(1,1,5,1))
for(i in 1:p){
  plot(X_level0[,i], y_level0, xlab = '', ylab = '', main = colnames(X_level0)[i])
}
mtext('NPP', outer = TRUE, side = 3, cex = 2, line = 2)


yanom_level0 <- YAnom_level0[,'npp_nlim_lnd_sum']

par(mfrow = c(5,7), mar = c(3,1,3,1), oma = c(1,1,5,1))
for(i in 1:p){
  plot(X_level0[,i], yanom_level0, xlab = '', ylab = '', main = colnames(X_level0)[i])
}
mtext('NPP change over time', outer = TRUE, side = 3, cex = 2, line = 2)

1.12 Relationship between modern NPP and change since 1850.

Some outputs (e.g fLuc, fHarvest) have an almost perfect 1:1 relationship between modern value and change, some (nbp, npp, treeFrac) quite or moderately strong, and some (csoil, cveg) very weak or non-existant.


par(mfrow = c(4,7), mar = c(3,1,3,1), oma = c(4,5,1,1))

pdash <- ncol(Y_level0)

for(i in 1:pdash){
  
  y_level0 <- Y_level0[,i]
  yanom_level0 <- YAnom_level0[,i]
  
  plot(y_level0, yanom_level0, xlab = '', ylab = '', main = colnames(Y_level0)[i])
}

mtext(text = 'Modern value', side = 1, line = 2, outer = TRUE, cex = 2)
mtext(text = 'Change', side = 2, line = 2, outer = TRUE, cex = 2)

1.13 A clear threshold in the F0 parameter for NPP

It appears that this ensemble is less “clear cut” in having an output that clearly distinguishes between “failed” (or close to it), and “not failed”.

Having said that, having an F0 over a threshold seems to kill the carbon cycle, as before. Here, we’ve set a threshold of 0.9 (on the normalised scale) for F0, and we remove members of the ensemble with a larger F0 than that when we build emulators.

NA
NA
NA
NA
NA

1.14 Level 1 constraint - remove ensemble members with F0 above threshold

The level 1 constraint removes any input with F0 greater than 0.9 (normalised), which removes many of the zero-carbon-cycle members up front. There are 424 ensmble members remaining.

This does constraint sequentially, which may not be a good idea.

tsAnomaly <- function(nc, variable, startix = 1:20, endix = 144:164){

  # A basic function to read a variable and calculate the anomaly at the end of the run
  dat <- ncvar_get(nc, variable)
  endMean <- mean(dat[endix])
  startMean <- mean(dat[startix])
  out <- endMean - startMean
  out
}

tsAnomaly(nc = nc, variable = "npp_nlim_lnd_mean")
[1] 2.410932e-09

1.14.1 Comparison of level 0 and level 1 emulators for NPP (modern value)


par(mfrow = c(4, 8), mar = c(4,3,2,1))

for(i in 1:d){
  
  hist(X_nlevel0[,i], xlim = c(0,1), breaks = seq(from=0, to = 1, by = 0.1), col = 'grey', main = '', ylim = c(0,9),
       border = 'white', xlab = colnames(X_nlevel0)[i], ylab = '', las = 1, cex.lab = 1.5)
}

# Plot the regular km emulator. Doesn’t look great.

plot(em_npp_level0)

plot(em_npp_level1)

1.14.2 Leave-one-out summaries of NPP emulators


par(mfrow = c(2,1))
plot(lhs$f0_io, datmat[, 'npp_nlim_lnd_sum'], main = 'Multiplication factor', xlab = 'f0_io', ylab = 'NPP sum')
plot(X_level0[,'f0_io'], Y_level0[, 'npp_nlim_lnd_sum'], xlab = 'f0_io', main = 'Normalized', ylab = 'NPP sum')
abline(v = 0.9)

em_npp_level0 <- km(~., design = X_level0,  response = y_level0)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 2 2 2 2 1.998154 1.997409 2 2 2 2 2 2 2 2 2 1.999201 2 1.996693 2 2 2 2 2 2 1.995643 1.998832 2 2 2 2 
  - best initial criterion value(s) :  -1843.987 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=         1844  |proj g|=       1.8323
At iterate     1  f =         1841  |proj g|=         1.932
At iterate     2  f =       1832.2  |proj g|=        1.7965
ys=-1.126e+00  -gs= 8.291e+00, BFGS update SKIPPED
At iterate     3  f =       1824.5  |proj g|=        1.7302
At iterate     4  f =       1817.2  |proj g|=        1.6877
At iterate     5  f =       1815.1  |proj g|=        1.9246
At iterate     6  f =       1812.3  |proj g|=        1.6337
At iterate     7  f =       1811.5  |proj g|=        1.6161
At iterate     8  f =       1808.8  |proj g|=        1.8958
At iterate     9  f =       1806.3  |proj g|=        1.8748
At iterate    10  f =       1802.3  |proj g|=        1.6391
At iterate    11  f =       1801.5  |proj g|=        1.5917
At iterate    12  f =       1799.8  |proj g|=        1.8831
At iterate    13  f =       1798.4  |proj g|=        1.2511
At iterate    14  f =       1797.5  |proj g|=        1.4136
At iterate    15  f =       1796.5  |proj g|=        1.5017
At iterate    16  f =       1796.1  |proj g|=        1.4701
At iterate    17  f =         1795  |proj g|=        1.8869
At iterate    18  f =         1795  |proj g|=        1.7583
At iterate    19  f =       1794.8  |proj g|=        1.7511
At iterate    20  f =       1794.6  |proj g|=        1.8834
At iterate    21  f =       1794.3  |proj g|=        1.8902
At iterate    22  f =       1793.4  |proj g|=        1.9002
At iterate    23  f =       1793.1  |proj g|=        1.8917
At iterate    24  f =       1792.8  |proj g|=         1.465
At iterate    25  f =       1792.6  |proj g|=        1.3879
At iterate    26  f =       1792.1  |proj g|=         1.811
At iterate    27  f =       1791.6  |proj g|=        1.8062
At iterate    28  f =       1791.3  |proj g|=        1.7986
At iterate    29  f =       1791.2  |proj g|=        1.5415
At iterate    30  f =       1791.1  |proj g|=        1.5681
At iterate    31  f =         1791  |proj g|=        1.1798
At iterate    32  f =         1791  |proj g|=         1.177
At iterate    33  f =         1791  |proj g|=        1.1717
At iterate    34  f =         1791  |proj g|=        1.1686
At iterate    35  f =       1790.9  |proj g|=         1.161
At iterate    36  f =       1790.4  |proj g|=        1.8051
At iterate    37  f =       1790.3  |proj g|=        1.7958
At iterate    38  f =       1790.2  |proj g|=       0.99558
At iterate    39  f =       1790.2  |proj g|=        1.8831
At iterate    40  f =       1790.1  |proj g|=        1.8842
At iterate    41  f =       1789.9  |proj g|=        1.8844
At iterate    42  f =       1789.8  |proj g|=         1.883
At iterate    43  f =       1789.7  |proj g|=       0.85804
At iterate    44  f =       1789.7  |proj g|=        1.2313
At iterate    45  f =       1789.7  |proj g|=        1.7874
At iterate    46  f =       1789.6  |proj g|=        1.7903
At iterate    47  f =       1789.5  |proj g|=        1.7899
At iterate    48  f =       1789.5  |proj g|=        1.7855
At iterate    49  f =       1789.4  |proj g|=        1.6657
At iterate    50  f =       1789.4  |proj g|=        1.4186
At iterate    51  f =       1789.4  |proj g|=        1.8803
At iterate    52  f =       1789.3  |proj g|=       0.73343
At iterate    53  f =       1789.2  |proj g|=       0.79817
At iterate    54  f =       1789.1  |proj g|=        1.7907
At iterate    55  f =       1789.1  |proj g|=        1.4231
At iterate    56  f =         1789  |proj g|=        1.4874
At iterate    57  f =         1789  |proj g|=        1.3247
At iterate    58  f =       1788.9  |proj g|=        1.8776
At iterate    59  f =       1788.8  |proj g|=       0.58767
At iterate    60  f =       1788.8  |proj g|=       0.63545
At iterate    61  f =       1788.8  |proj g|=       0.71919
At iterate    62  f =       1788.8  |proj g|=       0.73157
At iterate    63  f =       1788.8  |proj g|=       0.70156
At iterate    64  f =       1788.8  |proj g|=       0.66511
At iterate    65  f =       1788.7  |proj g|=       0.54998
At iterate    66  f =       1788.7  |proj g|=        1.8757
At iterate    67  f =       1788.7  |proj g|=       0.63942
At iterate    68  f =       1788.7  |proj g|=        0.6508
At iterate    69  f =       1788.7  |proj g|=       0.54948
At iterate    70  f =       1788.7  |proj g|=       0.41199
At iterate    71  f =       1788.7  |proj g|=        0.2168
At iterate    72  f =       1788.7  |proj g|=       0.21574
At iterate    73  f =       1788.7  |proj g|=       0.38684
At iterate    74  f =       1788.7  |proj g|=       0.47402
At iterate    75  f =       1788.7  |proj g|=       0.45564
At iterate    76  f =       1788.7  |proj g|=        1.8721
At iterate    77  f =       1788.7  |proj g|=       0.39459
At iterate    78  f =       1788.7  |proj g|=       0.26428
At iterate    79  f =       1788.7  |proj g|=       0.34423
At iterate    80  f =       1788.7  |proj g|=       0.24843
At iterate    81  f =       1788.7  |proj g|=       0.15055
At iterate    82  f =       1788.7  |proj g|=       0.21405
At iterate    83  f =       1788.7  |proj g|=      0.074636
At iterate    84  f =       1788.7  |proj g|=      0.053125
At iterate    85  f =       1788.7  |proj g|=       0.13013
At iterate    86  f =       1788.7  |proj g|=       0.10912
At iterate    87  f =       1788.7  |proj g|=      0.097971
At iterate    88  f =       1788.7  |proj g|=      0.056177
At iterate    89  f =       1788.7  |proj g|=      0.032267
At iterate    90  f =       1788.7  |proj g|=       0.01778

iterations 90
function evaluations 102
segments explored during Cauchy searches 96
BFGS updates skipped 1
active bounds at final generalized Cauchy point 23
norm of the final projected gradient 0.0177803
final function value 1788.68

F = 1788.68
final  value 1788.679293 
converged
em_npp_level1 <- km(~., design = X_level1,  response = y_level1)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 2 1.995574 2 1.998154 1.790352 2 2 2 1.998084 2 2 2 2 2 1.999201 2 1.996693 1.998361 2 2 1.995738 2 1.993455 1.995643 1.998832 2 2 2 2 
  - best initial criterion value(s) :  -6188.61 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       6188.6  |proj g|=       1.5726
At iterate     1  f =       6136.6  |proj g|=        1.7711
At iterate     2  f =       6124.5  |proj g|=        1.7375
At iterate     3  f =       6102.1  |proj g|=          1.54
At iterate     4  f =       6095.6  |proj g|=         1.926
At iterate     5  f =       6083.4  |proj g|=         1.166
At iterate     6  f =       6080.3  |proj g|=        1.1634
At iterate     7  f =       6076.7  |proj g|=        1.9021
At iterate     8  f =       6075.2  |proj g|=         1.911
At iterate     9  f =       6071.8  |proj g|=        1.9055
At iterate    10  f =       6064.3  |proj g|=        1.8912
At iterate    11  f =       6058.3  |proj g|=        1.2244
At iterate    12  f =         6058  |proj g|=        1.8887
At iterate    13  f =       6057.6  |proj g|=         1.894
At iterate    14  f =       6057.3  |proj g|=        1.8919
At iterate    15  f =         6057  |proj g|=        1.2244
At iterate    16  f =       6056.7  |proj g|=        1.2211
At iterate    17  f =       6055.4  |proj g|=        1.8931
At iterate    18  f =       6055.2  |proj g|=        1.8889
At iterate    19  f =       6054.8  |proj g|=        1.4117
At iterate    20  f =       6054.4  |proj g|=         1.414
At iterate    21  f =       6053.9  |proj g|=        1.8913
At iterate    22  f =       6053.6  |proj g|=         1.891
At iterate    23  f =       6053.2  |proj g|=        1.3425
At iterate    24  f =         6053  |proj g|=        1.3385
At iterate    25  f =       6052.8  |proj g|=        1.2233
At iterate    26  f =       6052.3  |proj g|=        1.8881
At iterate    27  f =       6052.3  |proj g|=        1.0774
At iterate    28  f =       6052.2  |proj g|=        1.0671
At iterate    29  f =         6052  |proj g|=        1.0482
At iterate    30  f =         6052  |proj g|=        1.0454
At iterate    31  f =       6051.9  |proj g|=        1.8877
At iterate    32  f =       6051.9  |proj g|=        1.8888
At iterate    33  f =       6051.9  |proj g|=        1.8864
At iterate    34  f =       6051.9  |proj g|=       0.90575
At iterate    35  f =       6051.9  |proj g|=       0.89448
At iterate    36  f =       6051.8  |proj g|=       0.74631
At iterate    37  f =       6051.8  |proj g|=        1.0388
At iterate    38  f =       6051.8  |proj g|=        1.3283
At iterate    39  f =       6051.7  |proj g|=        1.3266
At iterate    40  f =       6051.7  |proj g|=        1.8848
At iterate    41  f =       6051.7  |proj g|=         1.885
At iterate    42  f =       6051.7  |proj g|=       0.96601
At iterate    43  f =       6051.7  |proj g|=       0.15359
At iterate    44  f =       6051.7  |proj g|=       0.10377
At iterate    45  f =       6051.7  |proj g|=        0.1167
At iterate    46  f =       6051.7  |proj g|=        0.1168
At iterate    47  f =       6051.7  |proj g|=       0.11688
At iterate    48  f =       6051.7  |proj g|=       0.11685
At iterate    49  f =       6051.7  |proj g|=        0.1166
At iterate    50  f =       6051.7  |proj g|=       0.10972
At iterate    51  f =       6051.7  |proj g|=       0.16533
At iterate    52  f =       6051.7  |proj g|=      0.080658
At iterate    53  f =       6051.7  |proj g|=       0.36174
At iterate    54  f =       6051.7  |proj g|=       0.18435
At iterate    55  f =       6051.7  |proj g|=       0.11674
At iterate    56  f =       6051.7  |proj g|=       0.11677
At iterate    57  f =       6051.7  |proj g|=       0.10698
At iterate    58  f =       6051.7  |proj g|=      0.072612
At iterate    59  f =       6051.7  |proj g|=      0.043645

iterations 59
function evaluations 74
segments explored during Cauchy searches 83
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.0436446
final function value 6051.72

F = 6051.72
final  value 6051.720329 
converged
em_npp_level0_ms <- km(~., design = X_level0,  response = y_level0, multistart = 4)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 2 2 2 2 1.998154 1.997409 2 2 2 2 2 2 2 2 2 1.999201 2 1.996693 2 2 2 2 2 2 1.995643 1.998832 2 2 2 2 
  - best initial criterion value(s) :  -1840.591 -1841.288 -1844.501 -1844.688 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       1840.6  |proj g|=       1.8992
At iterate     1  f =         1835  |proj g|=        1.2966
At iterate     2  f =       1816.9  |proj g|=        1.8857
At iterate     3  f =       1811.1  |proj g|=        1.8535
At iterate     4  f =       1809.7  |proj g|=        1.8579
At iterate     5  f =       1806.4  |proj g|=        1.5074
At iterate     6  f =       1803.8  |proj g|=        1.8429
At iterate     7  f =       1802.8  |proj g|=        1.9053
At iterate     8  f =       1801.6  |proj g|=        1.4553
At iterate     9  f =       1801.3  |proj g|=        1.8287
At iterate    10  f =         1801  |proj g|=        1.8331
At iterate    11  f =       1799.5  |proj g|=         1.901
At iterate    12  f =       1798.6  |proj g|=        1.8816
At iterate    13  f =       1797.8  |proj g|=         1.821
At iterate    14  f =         1797  |proj g|=        1.3049
At iterate    15  f =       1794.4  |proj g|=        1.2057
At iterate    16  f =       1792.6  |proj g|=        1.5052
At iterate    17  f =       1791.6  |proj g|=        1.0431
At iterate    18  f =       1791.2  |proj g|=        1.0204
At iterate    19  f =       1791.1  |proj g|=        1.8728
At iterate    20  f =       1790.9  |proj g|=         1.873
At iterate    21  f =       1790.6  |proj g|=        1.8719
At iterate    22  f =       1790.5  |proj g|=       0.89679
At iterate    23  f =       1790.1  |proj g|=       0.82839
At iterate    24  f =       1789.9  |proj g|=       0.77349
At iterate    25  f =       1789.8  |proj g|=       0.99629
At iterate    26  f =       1789.7  |proj g|=       0.98579
At iterate    27  f =       1789.6  |proj g|=        1.7918
At iterate    28  f =       1789.5  |proj g|=        1.8717
At iterate    29  f =       1789.4  |proj g|=         1.351
At iterate    30  f =       1789.4  |proj g|=        1.2383
At iterate    31  f =       1789.3  |proj g|=       0.63725
At iterate    32  f =       1789.3  |proj g|=       0.63573
At iterate    33  f =       1789.3  |proj g|=        1.2897
At iterate    34  f =       1789.2  |proj g|=        1.3752
At iterate    35  f =       1789.2  |proj g|=       0.96652
At iterate    36  f =       1789.2  |proj g|=        0.6074
At iterate    37  f =       1789.1  |proj g|=        1.8729
At iterate    38  f =         1789  |proj g|=        1.3413
At iterate    39  f =         1789  |proj g|=       0.80837
At iterate    40  f =         1789  |proj g|=       0.78971
At iterate    41  f =       1788.9  |proj g|=        1.7915
At iterate    42  f =       1788.9  |proj g|=       0.74545
At iterate    43  f =       1788.8  |proj g|=       0.97496
At iterate    44  f =       1788.8  |proj g|=        1.8736
At iterate    45  f =       1788.8  |proj g|=        1.8731
At iterate    46  f =       1788.8  |proj g|=       0.49609
At iterate    47  f =       1788.8  |proj g|=       0.26876
At iterate    48  f =       1788.8  |proj g|=       0.43455
At iterate    49  f =       1788.8  |proj g|=       0.26835
At iterate    50  f =       1788.7  |proj g|=        1.3025
At iterate    51  f =       1788.7  |proj g|=        1.2469
At iterate    52  f =       1788.7  |proj g|=       0.64801
At iterate    53  f =       1788.7  |proj g|=       0.62234
At iterate    54  f =       1788.7  |proj g|=       0.98733
At iterate    55  f =       1788.7  |proj g|=        1.8724
At iterate    56  f =       1788.7  |proj g|=       0.18666
At iterate    57  f =       1788.7  |proj g|=       0.18511
At iterate    58  f =       1788.7  |proj g|=       0.21428
At iterate    59  f =       1788.7  |proj g|=       0.34715
At iterate    60  f =       1788.7  |proj g|=       0.18831
At iterate    61  f =       1788.7  |proj g|=       0.19901
At iterate    62  f =       1788.7  |proj g|=        1.2457
At iterate    63  f =       1788.7  |proj g|=       0.94195
At iterate    64  f =       1788.7  |proj g|=       0.42348
At iterate    65  f =       1788.7  |proj g|=       0.45832
At iterate    66  f =       1788.7  |proj g|=       0.30748
At iterate    67  f =       1788.7  |proj g|=       0.25212
At iterate    68  f =       1788.7  |proj g|=        1.0108
At iterate    69  f =       1788.7  |proj g|=       0.62535
At iterate    70  f =       1788.7  |proj g|=        0.3723
At iterate    71  f =       1788.7  |proj g|=       0.33613
At iterate    72  f =       1788.7  |proj g|=       0.19115
At iterate    73  f =       1788.7  |proj g|=       0.60743
At iterate    74  f =       1788.7  |proj g|=       0.16251
At iterate    75  f =       1788.7  |proj g|=        0.1533
At iterate    76  f =       1788.7  |proj g|=       0.21438
At iterate    77  f =       1788.7  |proj g|=       0.21472
At iterate    78  f =       1788.7  |proj g|=       0.13117
At iterate    79  f =       1788.7  |proj g|=        0.1301
At iterate    80  f =       1788.7  |proj g|=      0.036691
At iterate    81  f =       1788.7  |proj g|=      0.029554
At iterate    82  f =       1788.7  |proj g|=      0.051634
At iterate    83  f =       1788.7  |proj g|=      0.019406
At iterate    84  f =       1788.7  |proj g|=      0.034472
At iterate    85  f =       1788.7  |proj g|=      0.060315
At iterate    86  f =       1788.7  |proj g|=      0.032831
At iterate    87  f =       1788.7  |proj g|=       0.02779
At iterate    88  f =       1788.7  |proj g|=       0.02737
At iterate    89  f =       1788.7  |proj g|=      0.026581
At iterate    90  f =       1788.7  |proj g|=      0.013492
At iterate    91  f =       1788.7  |proj g|=      0.056896

iterations 91
function evaluations 108
segments explored during Cauchy searches 104
BFGS updates skipped 0
active bounds at final generalized Cauchy point 23
norm of the final projected gradient 0.0568956
final function value 1788.68

F = 1788.68
final  value 1788.679218 
converged
N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       1841.3  |proj g|=       1.8457
At iterate     1  f =       1827.2  |proj g|=        1.6626
At iterate     2  f =       1816.7  |proj g|=        1.6416
At iterate     3  f =       1813.6  |proj g|=        1.9367
At iterate     4  f =       1810.3  |proj g|=        1.4239
At iterate     5  f =       1807.8  |proj g|=        1.2668
At iterate     6  f =       1807.1  |proj g|=        1.9467
At iterate     7  f =       1806.3  |proj g|=        1.9301
At iterate     8  f =       1805.6  |proj g|=        1.4101
At iterate     9  f =       1805.2  |proj g|=        1.9325
At iterate    10  f =       1803.9  |proj g|=        1.9366
At iterate    11  f =       1800.9  |proj g|=        1.9409
At iterate    12  f =       1798.7  |proj g|=        1.9434
At iterate    13  f =       1798.4  |proj g|=        1.4098
At iterate    14  f =       1798.2  |proj g|=        1.3564
At iterate    15  f =         1798  |proj g|=        1.9417
At iterate    16  f =       1797.7  |proj g|=        1.6288
At iterate    17  f =       1796.7  |proj g|=        1.6209
At iterate    18  f =       1796.4  |proj g|=         1.936
At iterate    19  f =       1796.2  |proj g|=        1.1364
At iterate    20  f =       1795.6  |proj g|=        1.9343
At iterate    21  f =       1795.5  |proj g|=        1.4662
At iterate    22  f =       1795.3  |proj g|=        1.4608
At iterate    23  f =       1795.2  |proj g|=        1.9279
At iterate    24  f =       1795.1  |proj g|=        1.9304
At iterate    25  f =       1794.7  |proj g|=        1.9296
At iterate    26  f =       1794.7  |proj g|=        1.1735
At iterate    27  f =       1794.6  |proj g|=        1.1729
At iterate    28  f =       1794.6  |proj g|=        1.9274
At iterate    29  f =       1794.5  |proj g|=        1.9304
At iterate    30  f =       1794.4  |proj g|=         1.928
At iterate    31  f =       1794.4  |proj g|=        1.3428
At iterate    32  f =       1794.3  |proj g|=        1.2814
At iterate    33  f =       1794.3  |proj g|=         1.333
At iterate    34  f =       1794.3  |proj g|=        1.8995
At iterate    35  f =       1794.2  |proj g|=        1.9282
At iterate    36  f =       1794.1  |proj g|=        1.9307
At iterate    37  f =         1794  |proj g|=        1.9337
At iterate    38  f =         1794  |proj g|=        1.9301
At iterate    39  f =         1794  |proj g|=       0.83376
At iterate    40  f =       1793.9  |proj g|=         1.118
At iterate    41  f =       1793.9  |proj g|=        1.5683
At iterate    42  f =       1793.8  |proj g|=        1.5621
At iterate    43  f =       1793.8  |proj g|=        1.7678
At iterate    44  f =       1793.8  |proj g|=         1.928
At iterate    45  f =       1793.7  |proj g|=        1.9245
At iterate    46  f =       1793.7  |proj g|=       0.67906
At iterate    47  f =       1793.6  |proj g|=       0.53324
At iterate    48  f =       1793.6  |proj g|=       0.57473
At iterate    49  f =       1793.6  |proj g|=       0.33061
At iterate    50  f =       1793.6  |proj g|=         0.341
At iterate    51  f =       1793.6  |proj g|=       0.33962
At iterate    52  f =       1793.6  |proj g|=        0.3354
At iterate    53  f =       1793.6  |proj g|=        1.0482
At iterate    54  f =       1793.6  |proj g|=        1.7734
At iterate    55  f =       1793.6  |proj g|=        1.1694
At iterate    56  f =       1793.6  |proj g|=       0.28385
At iterate    57  f =       1793.6  |proj g|=       0.26585
At iterate    58  f =       1793.6  |proj g|=       0.21526
At iterate    59  f =       1793.6  |proj g|=        1.1788
At iterate    60  f =       1793.5  |proj g|=        1.0127
At iterate    61  f =       1793.5  |proj g|=        1.9242
At iterate    62  f =       1793.5  |proj g|=       0.38946
At iterate    63  f =       1793.5  |proj g|=       0.27952
At iterate    64  f =       1793.5  |proj g|=       0.24949
At iterate    65  f =       1793.5  |proj g|=       0.23862
At iterate    66  f =       1793.5  |proj g|=       0.78538
At iterate    67  f =       1793.5  |proj g|=        1.0766
At iterate    68  f =       1793.5  |proj g|=       0.76839
At iterate    69  f =       1793.5  |proj g|=       0.76669
At iterate    70  f =       1793.5  |proj g|=        1.9245
At iterate    71  f =       1793.5  |proj g|=       0.33263
At iterate    72  f =       1793.5  |proj g|=        0.1577
At iterate    73  f =       1793.5  |proj g|=       0.13078
At iterate    74  f =       1793.5  |proj g|=       0.12306
At iterate    75  f =       1793.5  |proj g|=       0.24376
At iterate    76  f =       1793.5  |proj g|=       0.30017
At iterate    77  f =       1793.5  |proj g|=         1.925
At iterate    78  f =       1793.5  |proj g|=       0.41291
At iterate    79  f =       1793.5  |proj g|=       0.36346
At iterate    80  f =       1793.5  |proj g|=        0.2116
At iterate    81  f =       1793.5  |proj g|=      0.094817
At iterate    82  f =       1793.5  |proj g|=       0.22363
At iterate    83  f =       1793.5  |proj g|=       0.29526
At iterate    84  f =       1793.5  |proj g|=         1.438
At iterate    85  f =       1793.5  |proj g|=       0.56409
At iterate    86  f =       1793.5  |proj g|=      0.077891
At iterate    87  f =       1793.5  |proj g|=       0.07784
At iterate    88  f =       1793.5  |proj g|=      0.028125
At iterate    89  f =       1793.5  |proj g|=       0.11856
At iterate    90  f =       1793.5  |proj g|=       0.14496
At iterate    91  f =       1793.5  |proj g|=      0.077867
At iterate    92  f =       1793.5  |proj g|=      0.077847
At iterate    93  f =       1793.5  |proj g|=      0.046362
At iterate    94  f =       1793.5  |proj g|=       0.03285
At iterate    95  f =       1793.5  |proj g|=      0.067001
At iterate    96  f =       1793.5  |proj g|=      0.077832
At iterate    97  f =       1793.5  |proj g|=       0.36176
At iterate    98  f =       1793.5  |proj g|=      0.028811
At iterate    99  f =       1793.5  |proj g|=      0.028298
At iterate   100  f =       1793.5  |proj g|=      0.077859
At iterate   101  f =       1793.5  |proj g|=      0.077922
final  value 1793.489261 
stopped after 101 iterations
N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       1844.5  |proj g|=       1.9446
At iterate     1  f =       1838.6  |proj g|=        1.6664
At iterate     2  f =       1821.5  |proj g|=        1.7352
At iterate     3  f =         1820  |proj g|=         1.949
At iterate     4  f =       1819.2  |proj g|=        1.6826
At iterate     5  f =       1817.9  |proj g|=        1.9038
At iterate     6  f =       1812.3  |proj g|=        1.4576
At iterate     7  f =       1806.2  |proj g|=        1.5271
At iterate     8  f =       1801.4  |proj g|=        1.9037
At iterate     9  f =       1800.2  |proj g|=        1.3158
At iterate    10  f =       1798.1  |proj g|=        1.2803
At iterate    11  f =       1797.5  |proj g|=        1.5149
At iterate    12  f =       1797.3  |proj g|=        1.8988
At iterate    13  f =       1797.1  |proj g|=        1.9054
At iterate    14  f =       1796.8  |proj g|=         1.913
At iterate    15  f =       1796.6  |proj g|=        1.9057
At iterate    16  f =       1796.3  |proj g|=       0.93391
At iterate    17  f =       1796.1  |proj g|=        0.9221
At iterate    18  f =       1795.8  |proj g|=       0.92711
At iterate    19  f =       1795.4  |proj g|=        1.8023
At iterate    20  f =       1795.4  |proj g|=        0.9197
At iterate    21  f =       1794.9  |proj g|=        1.8928
At iterate    22  f =       1794.9  |proj g|=        1.4632
At iterate    23  f =       1794.8  |proj g|=        1.4761
At iterate    24  f =       1794.7  |proj g|=        1.4636
At iterate    25  f =       1794.5  |proj g|=        1.4457
At iterate    26  f =       1794.2  |proj g|=        1.1544
At iterate    27  f =       1793.8  |proj g|=        1.7338
At iterate    28  f =       1793.5  |proj g|=        1.1692
At iterate    29  f =       1793.1  |proj g|=        1.8803
At iterate    30  f =       1792.5  |proj g|=         1.884
At iterate    31  f =       1792.4  |proj g|=       0.90038
At iterate    32  f =         1792  |proj g|=        1.7769
At iterate    33  f =       1791.9  |proj g|=        1.7735
At iterate    34  f =       1791.8  |proj g|=        1.8782
At iterate    35  f =       1791.6  |proj g|=        1.6841
At iterate    36  f =       1791.4  |proj g|=       0.83758
At iterate    37  f =       1791.1  |proj g|=        1.5247
At iterate    38  f =       1790.7  |proj g|=        1.4688
At iterate    39  f =       1790.6  |proj g|=        1.8823
At iterate    40  f =       1790.5  |proj g|=       0.89849
At iterate    41  f =       1790.4  |proj g|=       0.78778
At iterate    42  f =       1790.3  |proj g|=       0.78753
At iterate    43  f =       1790.1  |proj g|=       0.77988
At iterate    44  f =       1790.1  |proj g|=       0.77729
At iterate    45  f =         1790  |proj g|=        1.8799
At iterate    46  f =       1789.9  |proj g|=        1.7973
At iterate    47  f =       1789.9  |proj g|=       0.74416
At iterate    48  f =       1789.9  |proj g|=       0.73328
At iterate    49  f =       1789.8  |proj g|=       0.68398
At iterate    50  f =       1789.8  |proj g|=         1.307
At iterate    51  f =       1789.7  |proj g|=        1.3738
At iterate    52  f =       1789.7  |proj g|=        1.8109
At iterate    53  f =       1789.6  |proj g|=        1.3815
At iterate    54  f =       1789.6  |proj g|=       0.87545
At iterate    55  f =       1789.6  |proj g|=        1.1439
At iterate    56  f =       1789.4  |proj g|=        1.7894
At iterate    57  f =       1789.3  |proj g|=        1.7905
At iterate    58  f =       1789.3  |proj g|=        1.7929
At iterate    59  f =       1789.2  |proj g|=        1.8176
At iterate    60  f =       1789.1  |proj g|=        1.2114
At iterate    61  f =       1789.1  |proj g|=        1.1936
At iterate    62  f =       1788.9  |proj g|=       0.69571
At iterate    63  f =       1788.9  |proj g|=         1.872
At iterate    64  f =       1788.9  |proj g|=       0.73078
At iterate    65  f =       1788.9  |proj g|=       0.39127
At iterate    66  f =       1788.8  |proj g|=       0.84503
At iterate    67  f =       1788.8  |proj g|=       0.91146
At iterate    68  f =       1788.8  |proj g|=        0.4274
At iterate    69  f =       1788.8  |proj g|=       0.71837
At iterate    70  f =       1788.8  |proj g|=       0.88538
At iterate    71  f =       1788.8  |proj g|=        1.0321
At iterate    72  f =       1788.8  |proj g|=       0.53917
At iterate    73  f =       1788.8  |proj g|=        0.3419
At iterate    74  f =       1788.8  |proj g|=        0.3284
At iterate    75  f =       1788.8  |proj g|=        1.1285
At iterate    76  f =       1788.7  |proj g|=       0.61006
At iterate    77  f =       1788.7  |proj g|=       0.55693
At iterate    78  f =       1788.7  |proj g|=       0.85636
At iterate    79  f =       1788.7  |proj g|=       0.72264
At iterate    80  f =       1788.7  |proj g|=       0.39223
At iterate    81  f =       1788.7  |proj g|=       0.43084
At iterate    82  f =       1788.7  |proj g|=       0.33353
At iterate    83  f =       1788.7  |proj g|=       0.50591
At iterate    84  f =       1788.7  |proj g|=       0.36084
At iterate    85  f =       1788.7  |proj g|=        1.1291
At iterate    86  f =       1788.7  |proj g|=       0.42898
At iterate    87  f =       1788.7  |proj g|=       0.49812
At iterate    88  f =       1788.7  |proj g|=       0.38222
At iterate    89  f =       1788.7  |proj g|=        1.1761
At iterate    90  f =       1788.7  |proj g|=       0.13046
At iterate    91  f =       1788.7  |proj g|=      0.070866
At iterate    92  f =       1788.7  |proj g|=      0.049785
At iterate    93  f =       1788.7  |proj g|=      0.048225
At iterate    94  f =       1788.7  |proj g|=       0.13035
At iterate    95  f =       1788.7  |proj g|=       0.11851
At iterate    96  f =       1788.7  |proj g|=       0.16182
At iterate    97  f =       1788.7  |proj g|=       0.13024
At iterate    98  f =       1788.7  |proj g|=       0.05292
At iterate    99  f =       1788.7  |proj g|=      0.035912
At iterate   100  f =       1788.7  |proj g|=       0.03584
At iterate   101  f =       1788.7  |proj g|=      0.051226
final  value 1788.680281 
stopped after 101 iterations
N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       1844.7  |proj g|=       1.4672
At iterate     1  f =       1843.4  |proj g|=         1.968
At iterate     2  f =       1843.3  |proj g|=        1.8974
At iterate     3  f =       1842.6  |proj g|=        1.8426
At iterate     4  f =       1842.4  |proj g|=        1.1256
At iterate     5  f =       1842.2  |proj g|=        1.2435
At iterate     6  f =       1841.4  |proj g|=        1.9443
At iterate     7  f =       1841.1  |proj g|=        1.9516
At iterate     8  f =       1840.9  |proj g|=        1.6975
At iterate     9  f =       1840.8  |proj g|=        1.6862
At iterate    10  f =       1840.5  |proj g|=        1.9332
At iterate    11  f =         1840  |proj g|=        1.9268
At iterate    12  f =       1839.9  |proj g|=        0.9055
At iterate    13  f =       1839.7  |proj g|=       0.80229
At iterate    14  f =       1839.2  |proj g|=        1.7009
At iterate    15  f =         1839  |proj g|=        1.1931
At iterate    16  f =       1838.5  |proj g|=        1.1808
At iterate    17  f =       1838.1  |proj g|=        1.1838
At iterate    18  f =       1837.4  |proj g|=        1.9211
At iterate    19  f =       1837.4  |proj g|=        1.9225
At iterate    20  f =       1836.9  |proj g|=        1.9243
At iterate    21  f =       1836.6  |proj g|=        1.9223
At iterate    22  f =       1836.3  |proj g|=        1.9186
At iterate    23  f =       1836.1  |proj g|=        1.6348
At iterate    24  f =         1836  |proj g|=        1.1876
At iterate    25  f =         1834  |proj g|=        1.8623
ys=-2.675e+00  -gs= 1.141e+00, BFGS update SKIPPED
At iterate    26  f =       1823.9  |proj g|=         1.875
At iterate    27  f =       1823.5  |proj g|=        1.9059
At iterate    28  f =       1817.7  |proj g|=        1.9357
At iterate    29  f =       1816.6  |proj g|=        1.5494
At iterate    30  f =       1813.6  |proj g|=        1.4506
At iterate    31  f =       1807.9  |proj g|=        1.9079
At iterate    32  f =       1802.6  |proj g|=        1.9133
At iterate    33  f =       1801.2  |proj g|=        1.6175
At iterate    34  f =       1799.3  |proj g|=        1.6117
At iterate    35  f =         1799  |proj g|=        1.9328
At iterate    36  f =       1798.9  |proj g|=         1.585
At iterate    37  f =       1798.6  |proj g|=        1.9232
At iterate    38  f =       1798.5  |proj g|=        1.5529
At iterate    39  f =       1798.2  |proj g|=        1.3371
At iterate    40  f =       1797.7  |proj g|=        1.2875
At iterate    41  f =       1796.7  |proj g|=         1.908
At iterate    42  f =       1796.2  |proj g|=        1.9162
At iterate    43  f =       1795.7  |proj g|=       0.69953
At iterate    44  f =       1795.7  |proj g|=       0.76777
At iterate    45  f =       1795.5  |proj g|=       0.84032
At iterate    46  f =       1795.3  |proj g|=       0.93548
At iterate    47  f =       1795.3  |proj g|=       0.62274
At iterate    48  f =       1795.3  |proj g|=       0.62061
At iterate    49  f =       1795.2  |proj g|=        1.9126
At iterate    50  f =       1795.1  |proj g|=        1.9137
At iterate    51  f =       1794.9  |proj g|=        1.4085
At iterate    52  f =       1794.8  |proj g|=        1.4096
At iterate    53  f =       1794.8  |proj g|=        1.5586
At iterate    54  f =       1794.8  |proj g|=        1.9141
At iterate    55  f =       1794.7  |proj g|=        1.9198
At iterate    56  f =       1794.6  |proj g|=        1.9208
At iterate    57  f =       1794.4  |proj g|=        1.9157
At iterate    58  f =       1794.3  |proj g|=        1.5069
At iterate    59  f =       1794.3  |proj g|=       0.85699
At iterate    60  f =       1794.2  |proj g|=       0.87585
At iterate    61  f =       1794.1  |proj g|=        1.9104
At iterate    62  f =         1794  |proj g|=        1.9077
At iterate    63  f =       1793.9  |proj g|=        1.2773
At iterate    64  f =       1793.8  |proj g|=        0.9437
At iterate    65  f =       1793.6  |proj g|=        1.4982
At iterate    66  f =       1793.5  |proj g|=       0.79269
At iterate    67  f =       1793.5  |proj g|=        1.8986
At iterate    68  f =       1793.5  |proj g|=        1.7785
At iterate    69  f =       1793.4  |proj g|=       0.76164
At iterate    70  f =       1793.3  |proj g|=       0.59482
At iterate    71  f =       1793.2  |proj g|=        1.3774
At iterate    72  f =       1792.9  |proj g|=        1.8933
At iterate    73  f =       1792.9  |proj g|=        1.8916
At iterate    74  f =       1792.6  |proj g|=        1.8902
At iterate    75  f =       1792.5  |proj g|=        1.6151
At iterate    76  f =       1792.4  |proj g|=        1.8862
At iterate    77  f =       1792.3  |proj g|=        1.8926
At iterate    78  f =       1792.1  |proj g|=        1.8948
At iterate    79  f =       1791.8  |proj g|=        1.8897
At iterate    80  f =       1791.3  |proj g|=        1.7858
At iterate    81  f =         1791  |proj g|=        1.4047
At iterate    82  f =       1790.8  |proj g|=        1.3592
At iterate    83  f =       1790.5  |proj g|=        1.8858
At iterate    84  f =       1790.3  |proj g|=        1.8875
At iterate    85  f =       1790.3  |proj g|=        1.7917
At iterate    86  f =       1790.2  |proj g|=       0.80701
At iterate    87  f =       1790.2  |proj g|=        1.8841
At iterate    88  f =       1790.2  |proj g|=       0.87955
At iterate    89  f =       1790.2  |proj g|=       0.73846
At iterate    90  f =       1790.2  |proj g|=       0.73632
At iterate    91  f =       1790.1  |proj g|=        1.8842
At iterate    92  f =         1790  |proj g|=        1.8837
At iterate    93  f =         1790  |proj g|=        1.3858
At iterate    94  f =         1790  |proj g|=        1.2493
At iterate    95  f =         1790  |proj g|=       0.80289
At iterate    96  f =       1789.6  |proj g|=       0.89767
At iterate    97  f =       1789.5  |proj g|=       0.92278
At iterate    98  f =       1789.5  |proj g|=        0.8842
At iterate    99  f =       1789.5  |proj g|=        1.3099
At iterate   100  f =       1789.5  |proj g|=        1.8019
At iterate   101  f =       1789.4  |proj g|=        1.7896
final  value 1789.422897 
stopped after 101 iterations

* The 4 best values (multistart) obtained are:
 1788.679 1793.489 1788.68 1789.423 
* The model corresponding to the best one (1788.679) is stored. 
em_npp_level1_ms <- km(~., design = X_level1,  response = y_level1, multistart = 4)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 2 1.995574 2 1.998154 1.790352 2 2 2 1.998084 2 2 2 2 2 1.999201 2 1.996693 1.998361 2 2 1.995738 2 1.993455 1.995643 1.998832 2 2 2 2 
  - best initial criterion value(s) :  -6195.135 -6196.379 -6196.726 -6196.907 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       6195.1  |proj g|=       1.8927
At iterate     1  f =       6122.2  |proj g|=        1.5707
At iterate     2  f =       6117.3  |proj g|=        1.9163
At iterate     3  f =       6109.4  |proj g|=        1.4404
At iterate     4  f =         6104  |proj g|=        1.4243
At iterate     5  f =       6098.9  |proj g|=        1.4154
At iterate     6  f =       6097.3  |proj g|=        1.9323
At iterate     7  f =       6092.6  |proj g|=        1.8995
At iterate     8  f =       6091.8  |proj g|=        1.8937
At iterate     9  f =       6087.8  |proj g|=         1.378
At iterate    10  f =       6083.5  |proj g|=        1.9385
At iterate    11  f =       6082.3  |proj g|=        1.9369
At iterate    12  f =       6080.2  |proj g|=        1.9146
At iterate    13  f =       6079.5  |proj g|=        1.5762
At iterate    14  f =       6077.5  |proj g|=         1.908
At iterate    15  f =       6073.7  |proj g|=        1.9322
At iterate    16  f =       6067.8  |proj g|=        1.9248
At iterate    17  f =       6064.1  |proj g|=        1.9127
At iterate    18  f =       6063.5  |proj g|=        1.5983
At iterate    19  f =       6062.2  |proj g|=        1.6987
At iterate    20  f =         6059  |proj g|=        1.9046
At iterate    21  f =       6058.7  |proj g|=        1.9053
At iterate    22  f =       6058.2  |proj g|=        1.8994
At iterate    23  f =       6057.8  |proj g|=        1.8933
At iterate    24  f =       6057.5  |proj g|=        1.8985
At iterate    25  f =         6057  |proj g|=        1.8754
At iterate    26  f =       6056.7  |proj g|=        1.8971
At iterate    27  f =       6056.5  |proj g|=        1.8613
At iterate    28  f =       6056.3  |proj g|=        1.8537
At iterate    29  f =       6056.2  |proj g|=        1.8426
At iterate    30  f =         6056  |proj g|=         1.827
At iterate    31  f =       6055.9  |proj g|=        1.8242
At iterate    32  f =       6055.8  |proj g|=        1.8994
At iterate    33  f =       6055.6  |proj g|=        1.9037
At iterate    34  f =       6054.9  |proj g|=        1.7038
At iterate    35  f =       6054.3  |proj g|=        1.6206
At iterate    36  f =       6054.2  |proj g|=        1.6148
At iterate    37  f =       6053.9  |proj g|=        1.8984
At iterate    38  f =       6053.8  |proj g|=        1.9007
At iterate    39  f =       6053.8  |proj g|=        1.8987
At iterate    40  f =       6053.6  |proj g|=        1.5367
At iterate    41  f =       6053.5  |proj g|=        1.5078
At iterate    42  f =       6053.4  |proj g|=        1.4519
At iterate    43  f =         6053  |proj g|=        1.3688
At iterate    44  f =       6052.2  |proj g|=        1.1155
At iterate    45  f =       6052.1  |proj g|=        1.8915
At iterate    46  f =       6051.9  |proj g|=        1.8886
At iterate    47  f =       6051.8  |proj g|=        0.6479
At iterate    48  f =       6051.8  |proj g|=       0.52019
At iterate    49  f =       6051.8  |proj g|=       0.77044
At iterate    50  f =       6051.8  |proj g|=       0.82304
At iterate    51  f =       6051.8  |proj g|=       0.63234
At iterate    52  f =       6051.7  |proj g|=       0.64195
At iterate    53  f =       6051.7  |proj g|=       0.63411
At iterate    54  f =       6051.7  |proj g|=        0.5188
At iterate    55  f =       6051.7  |proj g|=       0.34326
At iterate    56  f =       6051.7  |proj g|=       0.26942
At iterate    57  f =       6051.7  |proj g|=       0.24872
At iterate    58  f =       6051.7  |proj g|=       0.28742
At iterate    59  f =       6051.7  |proj g|=       0.16146
At iterate    60  f =       6051.7  |proj g|=      0.058951
At iterate    61  f =       6051.7  |proj g|=      0.077783
At iterate    62  f =       6051.7  |proj g|=       0.14845
At iterate    63  f =       6051.7  |proj g|=       0.30758
At iterate    64  f =       6051.7  |proj g|=      0.047144
At iterate    65  f =       6051.7  |proj g|=      0.047412
At iterate    66  f =       6051.7  |proj g|=        0.1167
At iterate    67  f =       6051.7  |proj g|=      0.053942
At iterate    68  f =       6051.7  |proj g|=      0.081799
At iterate    69  f =       6051.7  |proj g|=       0.13639
At iterate    70  f =       6051.7  |proj g|=       0.11673
At iterate    71  f =       6051.7  |proj g|=      0.037407
At iterate    72  f =       6051.7  |proj g|=      0.030923

iterations 72
function evaluations 86
segments explored during Cauchy searches 83
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.0309228
final function value 6051.72

F = 6051.72
final  value 6051.720346 
converged
N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       6196.4  |proj g|=       1.8972
At iterate     1  f =       6104.3  |proj g|=        1.9187
At iterate     2  f =       6102.5  |proj g|=         1.217
At iterate     3  f =       6097.6  |proj g|=        1.2133
At iterate     4  f =       6097.1  |proj g|=        1.9059
At iterate     5  f =       6096.4  |proj g|=        1.8918
At iterate     6  f =       6094.9  |proj g|=        1.1924
At iterate     7  f =       6086.1  |proj g|=        1.0919
At iterate     8  f =       6083.9  |proj g|=        1.0843
At iterate     9  f =         6078  |proj g|=        1.0141
At iterate    10  f =       6073.3  |proj g|=         1.927
At iterate    11  f =       6068.5  |proj g|=        1.5493
At iterate    12  f =       6068.1  |proj g|=        1.6551
At iterate    13  f =       6064.5  |proj g|=        1.5904
At iterate    14  f =       6059.6  |proj g|=         1.624
At iterate    15  f =         6059  |proj g|=         1.913
At iterate    16  f =       6058.5  |proj g|=        1.9084
At iterate    17  f =       6057.7  |proj g|=        1.9016
At iterate    18  f =       6057.4  |proj g|=        1.7285
At iterate    19  f =       6057.3  |proj g|=        1.7251
At iterate    20  f =       6057.1  |proj g|=        1.8995
At iterate    21  f =       6056.7  |proj g|=        1.9029
At iterate    22  f =       6056.4  |proj g|=        1.7013
At iterate    23  f =       6056.3  |proj g|=         1.697
At iterate    24  f =       6056.1  |proj g|=         1.903
At iterate    25  f =       6055.8  |proj g|=        1.9044
At iterate    26  f =       6055.7  |proj g|=        1.6591
At iterate    27  f =       6055.5  |proj g|=        1.6404
At iterate    28  f =       6055.1  |proj g|=        1.9042
At iterate    29  f =         6055  |proj g|=        1.9019
At iterate    30  f =       6054.6  |proj g|=        1.5569
At iterate    31  f =       6054.5  |proj g|=        1.5441
At iterate    32  f =       6054.3  |proj g|=        1.5225
At iterate    33  f =         6054  |proj g|=        1.9007
At iterate    34  f =       6053.7  |proj g|=        1.9022
At iterate    35  f =       6053.6  |proj g|=        1.8998
At iterate    36  f =       6053.3  |proj g|=        1.3771
At iterate    37  f =       6053.2  |proj g|=        1.3353
At iterate    38  f =       6052.9  |proj g|=        1.4117
At iterate    39  f =       6052.7  |proj g|=        1.3568
At iterate    40  f =       6052.5  |proj g|=        1.8916
At iterate    41  f =       6052.4  |proj g|=        1.5815
At iterate    42  f =       6052.3  |proj g|=        1.3489
At iterate    43  f =       6052.2  |proj g|=        1.3407
At iterate    44  f =       6052.2  |proj g|=        1.0547
At iterate    45  f =       6052.2  |proj g|=        1.8873
At iterate    46  f =       6052.1  |proj g|=        1.8873
At iterate    47  f =       6052.1  |proj g|=        1.8877
At iterate    48  f =       6052.1  |proj g|=       0.82023
At iterate    49  f =       6052.1  |proj g|=       0.81418
At iterate    50  f =         6052  |proj g|=       0.92533
At iterate    51  f =         6052  |proj g|=        1.2702
At iterate    52  f =         6052  |proj g|=        1.2091
At iterate    53  f =       6051.9  |proj g|=        1.5493
At iterate    54  f =       6051.9  |proj g|=        1.8899
At iterate    55  f =       6051.8  |proj g|=        1.8877
At iterate    56  f =       6051.8  |proj g|=       0.84843
At iterate    57  f =       6051.7  |proj g|=       0.37131
At iterate    58  f =       6051.7  |proj g|=       0.32436
At iterate    59  f =       6051.7  |proj g|=       0.18853
At iterate    60  f =       6051.7  |proj g|=        1.1456
At iterate    61  f =       6051.7  |proj g|=       0.32984
At iterate    62  f =       6051.7  |proj g|=       0.20092
At iterate    63  f =       6051.7  |proj g|=        0.1608
At iterate    64  f =       6051.7  |proj g|=       0.31933
At iterate    65  f =       6051.7  |proj g|=       0.26402
At iterate    66  f =       6051.7  |proj g|=       0.11718
At iterate    67  f =       6051.7  |proj g|=       0.15761
At iterate    68  f =       6051.7  |proj g|=       0.12054
At iterate    69  f =       6051.7  |proj g|=       0.11695
At iterate    70  f =       6051.7  |proj g|=       0.10249
At iterate    71  f =       6051.7  |proj g|=       0.10612
At iterate    72  f =       6051.7  |proj g|=      0.070778
At iterate    73  f =       6051.7  |proj g|=       0.11673
At iterate    74  f =       6051.7  |proj g|=      0.038171
At iterate    75  f =       6051.7  |proj g|=      0.015529

iterations 75
function evaluations 91
segments explored during Cauchy searches 84
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.0155293
final function value 6051.72

F = 6051.72
final  value 6051.720333 
converged
N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       6196.7  |proj g|=       1.9574
At iterate     1  f =         6115  |proj g|=        1.3644
At iterate     2  f =       6111.3  |proj g|=         1.914
At iterate     3  f =       6099.9  |proj g|=        1.9015
At iterate     4  f =       6086.6  |proj g|=        1.0709
At iterate     5  f =       6077.5  |proj g|=       0.99043
At iterate     6  f =       6066.7  |proj g|=        1.5266
At iterate     7  f =       6065.6  |proj g|=        1.9003
At iterate     8  f =         6065  |proj g|=        1.9001
At iterate     9  f =       6061.9  |proj g|=         1.753
At iterate    10  f =       6059.6  |proj g|=        1.7391
At iterate    11  f =       6058.9  |proj g|=        1.8997
At iterate    12  f =       6058.2  |proj g|=        1.8991
At iterate    13  f =       6056.8  |proj g|=        1.6747
At iterate    14  f =       6056.6  |proj g|=        1.6683
At iterate    15  f =       6056.4  |proj g|=        1.8989
At iterate    16  f =       6056.1  |proj g|=        1.8981
At iterate    17  f =       6055.6  |proj g|=         1.624
At iterate    18  f =       6055.1  |proj g|=        1.5961
At iterate    19  f =       6054.8  |proj g|=        1.8977
At iterate    20  f =       6054.3  |proj g|=         1.512
At iterate    21  f =       6053.6  |proj g|=        1.4585
At iterate    22  f =       6053.3  |proj g|=        1.7092
At iterate    23  f =       6053.1  |proj g|=        1.8939
At iterate    24  f =       6052.4  |proj g|=        1.8916
At iterate    25  f =       6052.3  |proj g|=        1.1631
At iterate    26  f =       6052.2  |proj g|=        1.1507
At iterate    27  f =         6052  |proj g|=        1.0787
At iterate    28  f =       6051.9  |proj g|=        1.0719
At iterate    29  f =       6051.9  |proj g|=         1.888
At iterate    30  f =       6051.8  |proj g|=        1.0383
At iterate    31  f =       6051.8  |proj g|=        1.4133
At iterate    32  f =       6051.8  |proj g|=        1.4093
At iterate    33  f =       6051.7  |proj g|=         1.266
At iterate    34  f =       6051.7  |proj g|=       0.88851
At iterate    35  f =       6051.7  |proj g|=       0.34575
At iterate    36  f =       6051.7  |proj g|=       0.26128
At iterate    37  f =       6051.7  |proj g|=         0.186
At iterate    38  f =       6051.7  |proj g|=       0.33445
At iterate    39  f =       6051.7  |proj g|=       0.13104
At iterate    40  f =       6051.7  |proj g|=        0.1562
At iterate    41  f =       6051.7  |proj g|=       0.41036
At iterate    42  f =       6051.7  |proj g|=       0.39617
At iterate    43  f =       6051.7  |proj g|=        1.2855
At iterate    44  f =       6051.7  |proj g|=       0.20394
At iterate    45  f =       6051.7  |proj g|=       0.12996
At iterate    46  f =       6051.7  |proj g|=      0.084199
At iterate    47  f =       6051.7  |proj g|=       0.11659
At iterate    48  f =       6051.7  |proj g|=       0.18427
At iterate    49  f =       6051.7  |proj g|=       0.06944
At iterate    50  f =       6051.7  |proj g|=      0.051749
At iterate    51  f =       6051.7  |proj g|=      0.079272
At iterate    52  f =       6051.7  |proj g|=      0.019155
At iterate    53  f =       6051.7  |proj g|=      0.027772

iterations 53
function evaluations 65
segments explored during Cauchy searches 66
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.0277722
final function value 6051.72

F = 6051.72
final  value 6051.720351 
converged
N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       6196.9  |proj g|=       1.9125
At iterate     1  f =       6120.8  |proj g|=             2
At iterate     2  f =       6110.3  |proj g|=        1.9974
At iterate     3  f =       6109.1  |proj g|=        1.9939
At iterate     4  f =       6106.3  |proj g|=        1.9745
At iterate     5  f =       6095.6  |proj g|=        1.8847
At iterate     6  f =       6091.4  |proj g|=         1.843
At iterate     7  f =       6076.2  |proj g|=        1.9074
At iterate     8  f =       6074.9  |proj g|=        1.6242
At iterate     9  f =       6074.4  |proj g|=        1.6527
At iterate    10  f =       6068.6  |proj g|=        1.8212
At iterate    11  f =         6068  |proj g|=        1.7873
At iterate    12  f =       6066.9  |proj g|=        1.8921
At iterate    13  f =       6065.7  |proj g|=        1.8899
At iterate    14  f =       6063.7  |proj g|=        1.8237
At iterate    15  f =       6062.4  |proj g|=         1.841
At iterate    16  f =       6059.2  |proj g|=        1.8905
At iterate    17  f =       6058.3  |proj g|=        1.8317
At iterate    18  f =       6057.8  |proj g|=        1.8881
At iterate    19  f =       6057.3  |proj g|=        1.8166
At iterate    20  f =         6056  |proj g|=        1.7854
At iterate    21  f =       6055.5  |proj g|=        1.7532
At iterate    22  f =       6055.3  |proj g|=        1.9023
At iterate    23  f =         6055  |proj g|=         1.904
At iterate    24  f =       6054.6  |proj g|=         1.899
At iterate    25  f =       6054.5  |proj g|=        1.8935
At iterate    26  f =       6054.1  |proj g|=        1.6674
At iterate    27  f =       6053.7  |proj g|=        1.6291
At iterate    28  f =       6053.4  |proj g|=        1.8916
At iterate    29  f =       6053.3  |proj g|=        1.5882
At iterate    30  f =       6053.2  |proj g|=        1.5729
At iterate    31  f =       6053.2  |proj g|=        1.5673
At iterate    32  f =       6052.1  |proj g|=        1.2714
At iterate    33  f =       6052.1  |proj g|=        1.8838
At iterate    34  f =       6052.1  |proj g|=        1.8846
At iterate    35  f =       6051.9  |proj g|=        1.8848
At iterate    36  f =       6051.8  |proj g|=       0.91751
At iterate    37  f =       6051.8  |proj g|=       0.94406
At iterate    38  f =       6051.7  |proj g|=       0.50186
At iterate    39  f =       6051.7  |proj g|=       0.20636
At iterate    40  f =       6051.7  |proj g|=       0.17977
At iterate    41  f =       6051.7  |proj g|=       0.15895
At iterate    42  f =       6051.7  |proj g|=       0.14708
At iterate    43  f =       6051.7  |proj g|=       0.19519
At iterate    44  f =       6051.7  |proj g|=       0.10793
At iterate    45  f =       6051.7  |proj g|=       0.61841
At iterate    46  f =       6051.7  |proj g|=      0.034534
At iterate    47  f =       6051.7  |proj g|=      0.033439

iterations 47
function evaluations 56
segments explored during Cauchy searches 54
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.033439
final function value 6051.72

F = 6051.72
final  value 6051.720533 
converged

* The 4 best values (multistart) obtained are:
 6051.72 6051.72 6051.72 6051.721 
* The model corresponding to the best one (6051.72) is stored. 

loo_npp_level0 <- leaveOneOut.km(em_npp_level0, type = 'UK', trend.reestim = TRUE)
loo_npp_level1 <- leaveOneOut.km(em_npp_level1, type = 'UK', trend.reestim = TRUE)

RMSE ( loo_npp_level0$mean, y_level0)
[1] 10.81138
RMSE ( loo_npp_level1$mean, y_level1)
[1] 369553.5
# How about MAE over the range
prop_mae <- function(Y, Ypred){
  # mean absolute error as a proportion of the range of output
  
  absdiff <- abs(diff(range(Y)))
  
  mae <- MAE(Y, Ypred)
  
  propmae <- (mae / absdiff) * 100
  
  propmae
  
}

prop_mae(y_level0, loo_npp_level0$mean)
[1] 8.354225
prop_mae(y_level1, loo_npp_level1$mean)
[1] 5.220873
NA
NA
NA
NA

1.15 Constrain first and then do sensitivity analysis?

The problem with doing constraint first is that you end up with a non-hypercube shaped input space (corners have been knocked off by constraint), which is not ideal. We might therefore want different sensitivity measures for pre- and post-constrained ensemble.


# MOVE THIS TO IMPTOOLS OR EMTOOLS
# Given a km model, produce some error statistics

# It doesn't look like Multistart makes a big difference at all for NPP
errstats_npp_level0 <- kmLooStats(km = em_npp_level0)
errstats_npp_level0_ms <- kmLooStats(km = em_npp_level0_ms)

errstats_npp_level1 <- kmLooStats(km = em_npp_level1)
errstats_npp_level1_ms <- kmLooStats(km = em_npp_level1_ms)


# proportional mean absolute error
errstats_npp_level0$pmae
[1] 8.354225
errstats_npp_level0_ms$pmae
[1] 8.353783
errstats_npp_level1$pmae
[1] 5.220873
errstats_npp_level1_ms$pmae
[1] 5.220881
# DiceEval is useful but slow/awkward

# DE_em_npp_level0 <- modelFit(X = X_level0, Y = y_level0, type = 'Kriging', formula = ~. )
# DE_em_npp_level1 <- modelFit(X = X_level1, Y = y_level1, type = 'Kriging', formula = ~. )

# npp_em_cv_level0 <- crossValidation(DE_em_npp_level0, 5)
# npp_em_cv_level1  <- crossValidation(DE_em_npp_level1, 5)

#sensvar needs to go into emtools with oaat_design
sensvar <- function(oaat_pred, n, d){
  # Calculate variance as a global sensitivity meansure
  out = rep(NA,d)
  for(i in 1:d){
    ix = seq(from = ((i*n) - (n-1)), to =  (i*n), by = 1)
    out[i] = var(oaat_pred$mean[ix])
  }
  out
}
twoStep_glmnet <- function(X, y, nugget=NULL, nuggetEstim=FALSE, noiseVar=NULL, seed=NULL, trace=FALSE, maxit=100,
                          REPORT=10, factr=1e7, pgtol=0.0, parinit=NULL, popsize=100){
  # Use lasso to reduce input dimension of emulator before
  # building.
  control_list = list(trace=trace, maxit=maxit, REPORT=REPORT, factr=factr, pgtol=pgtol, pop.size=popsize)
  xvars = colnames(X)
  data = data.frame(response=y, x=X)
  colnames(data) <- c("response", xvars)
  nval = length(y)
  
  # fit a lasso by cross validation
  library(glmnet)
  fit_glmnet_cv = cv.glmnet(x=X,y=y)
  
  # The labels of the retained coefficients are here
  # (retains intercept at index zero)
  coef_i = (coef(fit_glmnet_cv, s = "lambda.1se"))@i
  labs = labels(coef(fit_glmnet_cv, s = "lambda.1se"))[[1]]
  labs = labs[-1] # remove intercept
  glmnet_retained = labs[coef_i]
  
  start_form = as.formula(paste("~ ", paste(glmnet_retained , collapse= "+")))
  m = km(start_form, design=X, response=y, nugget=nugget, parinit=parinit,
         nugget.estim=nuggetEstim, noise.var=noiseVar, control=control_list)
  
  return(list(x=X, y=y, nugget=nugget, nuggetEstim=nuggetEstim,
              noiseVar=noiseVar, emulator=m, seed=seed, coefs=m@covariance@range.val,
              trends=m@trend.coef, meanTerms=all.vars(start_form), fit_glmnet_cv=fit_glmnet_cv))
}

1.16 Initial sensitivity Matrix

It looks as though bwl_io is very influential across a number of variables, even though it didn’t appear that interesting in the parginal plots. Why is that?


twoStep_sens <- function(X, y, n=21, predtype = 'UK', nugget=NULL, nuggetEstim=FALSE, noiseVar=NULL, seed=NULL, trace=FALSE, maxit=100,
                        REPORT=10, factr=1e7, pgtol=0.0, parinit=NULL, popsize=100){
  # Sensitivity analysis with twoStep emulator. 
  # Calculates the variance of the output varied one at a time across each input.
  d = ncol(X)
  X_norm <- normalize(X)
  X_oaat <- oaat_design(X_norm, n, med = TRUE)
  colnames(X_oaat) = colnames(X)
  
  twoStep_em = twoStep_glmnet(X=X, y=y, nugget=nugget, nuggetEstim=nuggetEstim, noiseVar=noiseVar,
                              seed=seed, trace=trace, maxit=maxit,
                              REPORT=REPORT, factr=factr, pgtol=pgtol,
                              parinit=parinit, popsize=popsize)
  
  oaat_pred = predict(twoStep_em$emulator, newdata = X_oaat, type = predtype)
  
  sens = sensvar(oaat_pred = oaat_pred, n=n, d=d)
  out = sens
  out
}

if (file.exists("oat_twostep.rdata")) {
  load("oat_twostep.rdata")
} else {
oat_test <- twoStep_sens(X = X_level1, y = y_level1)


save(oat_test, file = "oat_twostep.rdata")
}

1.17 Re-examine bwl_io

A closer look at bwl_io now that the impact of f0_io has been removed shows a large number of “zero” NPP when bwl_io is at low values, which could well be the source of apparent sensitivity.

Take only higher values of bwl_io for the next round of constraints.

y_names_sum <- c('nbp_lnd_sum', 'fLuc_lnd_sum', 'npp_nlim_lnd_sum', 'cSoil_lnd_sum',
            'cVeg_lnd_sum', 'landCoverFrac_lnd_sum', 'fHarvest_lnd_sum',
            'lai_lnd_sum', 'rh_lnd_sum', 'treeFrac_lnd_sum', 'c3PftFrac_lnd_sum', 
            'c4PftFrac_lnd_sum', 'shrubFrac_lnd_sum', 'baresoilFrac_lnd_sum')




if (file.exists("oaat_Y.rdata")) {
  load("oaat_Y.rdata")
} else {
  
  
oat_var_sensmat_Y <- matrix(NA, nrow = length(y_names_sum), ncol = ncol(X_level1))

for(i in 1:length(y_names_sum)){
  
  yname <- y_names_sum[i]
  y <- Y_level1[, yname]
  oat <- twoStep_sens(X = X_level1, y = y)
  oat_var_sensmat_Y[i, ] <- oat
}

save(y_names_sum, oat_var_sensmat_Y, file = "oaat_Y.rdata")
}

2 Remove ensemble members with low b_wl and see if the sensitivity analyses change and the emulators get better.

# normalize the sensitivity matrix
colnames(oat_var_sensmat_Y) <- colnames(X_level1)
rownames(oat_var_sensmat_Y) <- y_names_sum

#test <- normalize(t(oat.var.sensmat))

#image(test)
#par()
heatmap(oat_var_sensmat_Y, Rowv = NA, Colv = NA, mar = c(10,10), scale = 'row')

heatmap(oat_var_sensmat_Y, mar = c(10,10), scale = 'row')


normsens_Y <- normalize(t(oat_var_sensmat_Y))

par(mar = c(12,12,5,2))
image(normsens_Y, axes = FALSE, col = blues)
axis(1, at = seq(from = 0, to = 1, length.out = p), labels = colnames(X_level1), las = 2)
axis(2, at = seq(from = 0, to = 1, length.out = length(y_names_sum)), labels = y_names_sum, las = 1)
mtext('One-at-a-time sensitivity, variance across level 1 ensemble', side = 3, adj = 0, line = 2, cex = 1.8)

# Plot the regular km emulator.


p <- ncol(X_level1)

y_level1 <- Y_level1[,'npp_nlim_lnd_sum']

par(mfrow = c(5,7), mar = c(3,1,3,1))
for(i in 1:p){
  plot(X_level1[,i], y_level1, xlab = '', ylab = '', main = colnames(X_level1)[i])
}

level1a_ix <- which(X_level0[, 'f0_io'] < 0.9 & X_level0[, 'b_wl_io'] > 0.15 )

X_level1a <- X_level0[level1a_ix, ]
Y_level1a <- Y_level0[level1a_ix,]

YAnom_level1a <- YAnom_level0[level1a_ix, ]

y_level1a <- Y_level1a[, 'npp_nlim_lnd_sum']
em_level1a <- km(~., design = X_level1a,  response = y_level1a)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -5133.394 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       5133.4  |proj g|=       1.8131
At iterate     1  f =         5121  |proj g|=        1.2902
At iterate     2  f =       5116.2  |proj g|=        1.1233
At iterate     3  f =       5113.3  |proj g|=        1.9533
At iterate     4  f =       5109.2  |proj g|=        1.8973
At iterate     5  f =       5108.8  |proj g|=        1.8844
At iterate     6  f =       5107.7  |proj g|=        1.8317
At iterate     7  f =       5106.8  |proj g|=        1.7101
At iterate     8  f =       5105.7  |proj g|=        1.6716
ys=-1.681e-02  -gs= 1.079e+00, BFGS update SKIPPED
At iterate     9  f =       5104.7  |proj g|=        1.6302
ys=-1.744e-02  -gs= 1.071e+00, BFGS update SKIPPED
At iterate    10  f =         5100  |proj g|=        1.4684
At iterate    11  f =       5098.1  |proj g|=        1.4639
ys=-1.189e-01  -gs= 1.821e+00, BFGS update SKIPPED
At iterate    12  f =       5096.7  |proj g|=        1.4348
At iterate    13  f =       5085.8  |proj g|=        1.6376
At iterate    14  f =       5083.2  |proj g|=        1.5237
At iterate    15  f =       5082.4  |proj g|=        1.4883
At iterate    16  f =       5081.9  |proj g|=       0.95479
At iterate    17  f =       5081.1  |proj g|=       0.77253
At iterate    18  f =       5080.9  |proj g|=       0.78443
At iterate    19  f =       5080.6  |proj g|=        1.4664
At iterate    20  f =         5080  |proj g|=        1.4898
At iterate    21  f =       5079.9  |proj g|=       0.61139
At iterate    22  f =       5079.9  |proj g|=       0.51856
At iterate    23  f =       5079.8  |proj g|=       0.53696
At iterate    24  f =       5079.7  |proj g|=       0.52792
At iterate    25  f =       5079.7  |proj g|=       0.61936
At iterate    26  f =       5079.7  |proj g|=       0.48489
At iterate    27  f =       5079.7  |proj g|=       0.28752
At iterate    28  f =       5079.7  |proj g|=       0.30663
At iterate    29  f =       5079.7  |proj g|=       0.37981
At iterate    30  f =       5079.7  |proj g|=       0.24244
At iterate    31  f =       5079.7  |proj g|=       0.34063
At iterate    32  f =       5079.7  |proj g|=        0.1443
At iterate    33  f =       5079.7  |proj g|=       0.17564
At iterate    34  f =       5079.7  |proj g|=       0.18611
At iterate    35  f =       5079.7  |proj g|=       0.39674
At iterate    36  f =       5079.7  |proj g|=      0.080551
At iterate    37  f =       5079.7  |proj g|=      0.078492
At iterate    38  f =       5079.7  |proj g|=       0.10282
At iterate    39  f =       5079.7  |proj g|=       0.38568
At iterate    40  f =       5079.7  |proj g|=       0.14667
At iterate    41  f =       5079.7  |proj g|=      0.066404
At iterate    42  f =       5079.6  |proj g|=      0.079053
At iterate    43  f =       5079.6  |proj g|=      0.079532
At iterate    44  f =       5079.6  |proj g|=      0.090775
At iterate    45  f =       5079.6  |proj g|=      0.051122
At iterate    46  f =       5079.6  |proj g|=      0.044645
At iterate    47  f =       5079.6  |proj g|=      0.033494
At iterate    48  f =       5079.6  |proj g|=      0.054964
At iterate    49  f =       5079.6  |proj g|=      0.010217
At iterate    50  f =       5079.6  |proj g|=     0.0098125

iterations 50
function evaluations 60
segments explored during Cauchy searches 70
BFGS updates skipped 3
active bounds at final generalized Cauchy point 20
norm of the final projected gradient 0.00981252
final function value 5079.65

F = 5079.65
final  value 5079.648779 
converged

2.1 With b_wl truncated, we can clearly see the sensitivities change.

plot(em_level1a)

NA
NA
if (file.exists("oaat_level1a_Y.rdata")) {
  load("oaat_level1a_Y.rdata")
} else {
  
  
oat_var_sensmat_level1a_Y <- matrix(NA, nrow = length(y_names_sum), ncol = ncol(X_level1a))

for(i in 1:length(y_names_sum)){
  
  yname <- y_names_sum[i]
  y <- Y_level1a[, yname]
  oat <- twoStep_sens(X = X_level1a, y = y)
  oat_var_sensmat_level1a_Y[i, ] <- oat
}

save(y_names_sum, oat_var_sensmat_level1a_Y, file = "oaat_level1a_Y.rdata")
}

p <- ncol(X_level1a)

y_level1a <- Y_level1a[,'npp_nlim_lnd_sum']

par(mfrow = c(5,7), mar = c(3,1,3,1))
for(i in 1:p){
  plot(X_level1a[,i], y_level1a, xlab = '', ylab = '', main = colnames(X_level1a)[i], xlim = c(0,1))
}

# normalize the sensitivity matrix
colnames(oat_var_sensmat_level1a_Y) <- colnames(X_level1a)
rownames(oat_var_sensmat_level1a_Y) <- y_names_sum

#test <- normalize(t(oat.var.sensmat))

#image(test)
#par()
heatmap(oat_var_sensmat_level1a_Y, Rowv = NA, Colv = NA, mar = c(10,10), scale = 'row')

heatmap(oat_var_sensmat_level1a_Y, mar = c(10,10), scale = 'row')


normsens_level1a_Y <- normalize(t(oat_var_sensmat_level1a_Y))

par(mar = c(12,12,5,2))
image(normsens_level1a_Y, axes = FALSE, col = blues)
axis(1, at = seq(from = 0, to = 1, length.out = p), labels = colnames(X_level1a), las = 2)
axis(2, at = seq(from = 0, to = 1, length.out = length(y_names_sum)), labels = y_names_sum, las = 1)
mtext('One-at-a-time sensitivity, variance across level 1a ensemble', side = 3, adj = 0, line = 2, cex = 1.8)

2.2 Plot both sensitivity matrices on top of one another.

It looks as though both the absolute value and the change over time are controlled by the same parameters.

# This fails for "cVeg_lnd_sum"
# The result will be that some of the columns are repeated.

if (file.exists("oaat_YAnom.rdata")) {
  load("oaat_YAnom.rdata")
} else {

oat_var_sensmat_YAnom <- matrix(NA, nrow = length(y_names_sum), ncol = ncol(X_level1))

for(i in 1:length(y_names_sum)){
  
  yname <- y_names_sum[i]
  y <- YAnom_level1[, yname]
  try(oat <- twoStep_sens(X = X_level1, y = y))
  oat_var_sensmat_YAnom[i, ] <- oat
}

save(y_names_sum, oat_var_sensmat_YAnom, file = "oaat_YAnom.rdata")

}

2.3 How good are the emulators for each output?

The emulators appear to be at least capturing the broad response for all of the output variables.

First, plot the straight kriging emulators

# normalize the sensitivity matrix
colnames(oat_var_sensmat_YAnom) <- colnames(X_level1)
rownames(oat_var_sensmat_YAnom) <- y_names_sum

#test <- normalize(t(oat.var.sensmat))

#image(test)
#par()
heatmap(oat_var_sensmat_YAnom, Rowv = NA, Colv = NA, mar = c(10,10), scale = 'row')

heatmap(oat_var_sensmat_YAnom, mar = c(10,6), scale = 'row')


normsens_YAnom <- normalize(t(oat_var_sensmat_YAnom))

par(mar = c(12,12,5,2))
image(normsens_YAnom, axes = FALSE, col = blues)
axis(1, at = seq(from = 0, to = 1, length.out = p), labels = colnames(X_level1), las = 2)
axis(2, at = seq(from = 0, to = 1, length.out = length(y_names_sum)), labels = y_names_sum, las = 1)
mtext('One-at-a-time sensitivity, variance of historical change across level 1 ensemble', side = 3, adj = 0, line = 2, cex = 1.8)

par(mfrow = c(2,1), mar = c(12,12,5,2))

image(normsens_Y, axes = FALSE, col = blues)
axis(1, at = seq(from = 0, to = 1, length.out = p), labels = colnames(X_level1), las = 2)
axis(2, at = seq(from = 0, to = 1, length.out = length(y_names_sum)), labels = y_names_sum, las = 1)
mtext('One-at-a-time sensitivity, variance of historical change across level 1 ensemble', side = 3, adj = 0, line = 2, cex = 1.8)


image(normsens_YAnom, axes = FALSE, col = blues)
axis(1, at = seq(from = 0, to = 1, length.out = p), labels = colnames(X_level1), las = 2)
axis(2, at = seq(from = 0, to = 1, length.out = length(y_names_sum)), labels = y_names_sum, las = 1)
mtext('One-at-a-time sensitivity, variance of historical change across level 1 ensemble', side = 3, adj = 0, line = 2, cex = 1.8)

NA
NA

if (file.exists("km_emulators_Y.rdata")) {
  load("km_emulators_Y.rdata")
} else {
  
  emlist_km_Y <- vector(mode = 'list', length = length(y_names_sum))
  
  for(i in 1:length(y_names_sum)){
    yname <- y_names_sum[i]
    y <- Y_level1[, yname]
    
    em <- km(~., design = X_level1, response = y)
    emlist_km_Y[[i]] <- em
  }
  
  loolist_km_Y <- vector(mode = 'list', length = length(y_names_sum))
  
  for(i in 1:length(y_names_sum)){
    
    loo <- leaveOneOut.km(model = emlist_km_Y[[i]], type = 'UK', trend.reestim = TRUE)
    loolist_km_Y[[i]] <- loo
  }
  
  save(emlist_km_Y,loolist_km_Y, file = "km_emulators_Y.rdata")
}

3 km emulators for change in variables over time



loostats_km_Y <- vector(mode = 'list', length = length(y_names_sum))

for(i in 1:length(emlist_km_Y)){
  
  loostats <- kmLooStats(emlist_km_Y[[i]])
  loostats_km_Y[[i]] <- loostats
  print(loostats$pmae)
}
[1] 5.433077
[1] 5.142409
[1] 5.2209
[1] 4.193005
[1] 4.219396
[1] 4.531841
[1] 5.629425
[1] 8.565018
[1] 5.224583
[1] 9.223968
[1] 7.089
[1] 7.78196
[1] 6.900971
[1] 6.929568

Next, plot the twostep glmnet/km emulators

par(mfrow = c(4,4), mar = c(3,4,2,2), oma = c(4,4,4,0.1))
for(i in 1:length(loolist_km_Y)){
  
  y <- Y_level1[, y_names_sum[i]]
  loo <- loolist_km_Y[[i]]
  ylim <- range(c(loo$mean - (2*loo$sd), loo$mean + (2*loo$sd)) )
  plot(y, loo$mean, xlab = '', ylab = '', main = y_names_sum[i] , ylim = ylim, col = makeTransparent('black', 70),
       pch = 19)
  segments(x0 = y, y0 = loo$mean - (2*loo$sd)  , x1 = y , y1 = loo$mean + (2*loo$sd), col = makeTransparent('black', 70))
  abline(0,1)
  legend('bottomright',legend = paste('mae =',round(loostats_km_Y[[i]]$pmae,2),'%') , bty = 'n')

}

mtext('Actual', side = 1, line = 1, outer = TRUE, cex = 2 )
mtext('Predicted', side = 2, line = 0, outer = TRUE, cex = 2) 
mtext('Modern Value (Y)', side = 3, line = 0, outer = TRUE, cex = 2) 


if (file.exists("km_emulators_YAnom.rdata")) {
  load("km_emulators_YAnom.rdata")
} else {
  
  emlist_km_YAnom <- vector(mode = 'list', length = length(y_names_sum))
  
  for(i in 1:length(y_names_sum)){
    yname <- y_names_sum[i]
    y <- YAnom_level1[, yname]
    
    em <- km(~., design = X_level1, response = y)
    emlist_km_YAnom[[i]] <- em
  }
  
  loolist_km_YAnom <- vector(mode = 'list', length = length(y_names_sum))
  
  for(i in 1:length(y_names_sum)){
    
    loo <- leaveOneOut.km(model = emlist_km_YAnom[[i]], type = 'UK', trend.reestim = TRUE)
    loolist_km_YAnom[[i]] <- loo
  }
  
  save(emlist_km_YAnom,loolist_km_YAnom, file = "km_emulators_YAnom.rdata")
}

3.1 TwoStep emulator performance for modern values

par(mfrow = c(4,4), mar = c(3,4,2,2), oma = c(4,4,4,0.1))
for(i in 1:length(loolist_km_YAnom)){
  
  y <- YAnom_level1[, y_names_sum[i]]
  loo <- loolist_km_YAnom[[i]]
  ylim <- range(c(loo$mean - (2*loo$sd), loo$mean + (2*loo$sd)) )
  plot(y, loo$mean, xlab = '', ylab = '', main = y_names_sum[i] , ylim = ylim, col = makeTransparent('black', 70),
       pch = 19)
  segments(x0 = y, y0 = loo$mean - (2*loo$sd)  , x1 = y , y1 = loo$mean + (2*loo$sd), col = makeTransparent('black', 70))
  abline(0,1)
  

}

mtext('Actual', side = 1, line = 1, outer = TRUE, cex = 2 )
mtext('Predicted', side = 2, line = 0, outer = TRUE, cex = 2) 
mtext('Change over time (YAnom)', side = 3, line = 1, outer = TRUE, cex = 2) 

4 Compare Leave-one-out statistics for the two types of emulator

We use the leave-one-out Mean Absolute Error, expressed as a percentage of the range of the output across the ensemble. We find that the twostep emulatorisn’t significantly more accurate, and is indeed less accurate for tree fraction.

# Twostep glmnet emulators

if (file.exists("ts_emulators_Y.rdata")) {
  load("ts_emulators_Y.rdata")
} else {
  
  emlist_twoStep_glmnet_Y <- vector(mode = 'list', length = length(y_names_sum))
  
  for(i in 1:length(y_names_sum)){
    
    yname <- y_names_sum[i]
    y <- Y_level1[, yname]
    
    em <- twoStep_glmnet(X = X_level1, y = y)
    emlist_twoStep_glmnet_Y[[i]] <- em
  }
  
  loolist_twoStep_glmnet_Y <- vector(mode = 'list', length = length(y_names_sum))
  
  for(i in 1:length(y_names_sum)){
    
    loo <- leaveOneOut.km(model = emlist_twoStep_glmnet_Y[[i]]$emulator, type = 'UK', trend.reestim = TRUE)
    loolist_twoStep_glmnet_Y[[i]] <- loo
  }
  
  
  
  save(emlist_twoStep_glmnet_Y, loolist_twoStep_glmnet_Y, file = "ts_emulators_Y.rdata")

}
# Can get numerical performance using

loostats_twoStep_glmnet_Y <- vector(mode = 'list', length = length(y_names_sum))

for(i in 1:length(emlist_twoStep_glmnet_Y)){
  
  loostats <- kmLooStats(emlist_twoStep_glmnet_Y[[i]]$emulator)
  loostats_twoStep_glmnet_Y[[i]] <- loostats
  print(loostats$pmae)
}
[1] 5.410355
[1] 4.733929
[1] 5.215455
[1] 4.173501
[1] 4.03861
[1] 4.597044
[1] 5.501413
[1] 8.563912
[1] 5.213222
[1] 11.36184
[1] 7.260354
[1] 7.707121
[1] 6.725096
[1] 6.865819

5 History matching and generation of new ensemble members

To use History Matching, we need to specify targets for various model outputs. We treat these targets as “observations” with an uncertainty where a model run marked as “implausible” (beyond 3sd) matches the hard boundaries previously identified by A. Wiltshire as being desirable.

Choose the centre of the (implied) uniform distribution. cs_gb.target = (3000 - 750) / 2 = 1125 cv.target = (800 - 300) / 2 = 250 npp_n_gb.target = (80 - 35) / 2 = 22.5

nbp.target = 0 (gpp.target = 75) (runoff.target = 1)

(to do: visualise implausibility of design and loo emulated values of design as histogram)

par(mfrow = c(4,4), mar = c(3,4,2,2), oma = c(4,4,4,0.1))
for(i in 1:length(loolist_twoStep_glmnet_Y)){
  
  y <- Y_level1[, y_names_sum[i]]
  loo <- loolist_twoStep_glmnet_Y[[i]]
  ylim <- range(c(loo$mean - (2*loo$sd), loo$mean + (2*loo$sd)) )
  plot(y, loo$mean, xlab = '', ylab = '', main = y_names_sum[i] , ylim = ylim, col = makeTransparent('black', 70),
       pch = 19)
  segments(x0 = y, y0 = loo$mean - (2*loo$sd)  , x1 = y , y1 = loo$mean + (2*loo$sd), col = makeTransparent('black', 70))
  abline(0,1)
  legend('bottomright',legend = paste('mae =',round(loostats_twoStep_glmnet_Y[[i]]$pmae,2),'%') , bty = 'n')

}

mtext('Actual', side = 1, line = 1, outer = TRUE, cex = 2 )
mtext('Predicted', side = 2, line = 0, outer = TRUE, cex = 2) 
mtext('Modern Value (Y)', side = 3, line = 0, outer = TRUE, cex = 2) 

5.1 visualise the constraints



km_pmae <- sapply(loostats_km_Y, '[[', 'pmae')
ts_pmae <- sapply(loostats_twoStep_glmnet_Y, '[[', 'pmae')

par(mar = c(12,4,2,1), las =1 )
plot(1:length(y_names_sum), km_pmae,
     ylim = c(0,15), pch = 19,
     axes = FALSE, xlab = '', 
     ylab = 'LOO MAE (% of range)',
     cex = 1.2)
points(1:length(y_names_sum),ts_pmae , col= 'red', pch = 19, cex = 1.2)
legend('topleft', c('km emulator', 'twoStep emulator'), pch = 19, col = c('black', 'red'), pt.cex = 1.2)
axis (2)
par(las = 2)
axis(1, at = 1:length(y_names_sum), labels = y_names_sum)

5.2 Timeseries that match the constraints.

Plot the original ensemble, plus the stuff that matches the constraints. Include anomalies.


# Write an emulator wrapper

# Write a leave-one-out wrapper

# Create a list of emulator fits, for both km and twoStep methods.
# Use mclapply to build the lists
# use code from HDE package
# Make sure errors are handled adequately.


# Can we write it to use any emulator? (i.e km, twostep, something from another package?)

We find that adding a constraint to level 2 constrains the behaviour of the soil carbon pool, but not the vegetation carbon pool. Probably not a surprise, given the Soil Carbon pool (and changes) are much larger than the vegetation carbon pool.

#cSoil_ens_anom [toplevel_to_level_1a_ix, ]

par(mfrow= c(1,4), las = 1)

plotcol <- c(makeTransparent('black', 70))
overplotcol <- c(makeTransparent('tomato3', 200))


ylim = range(cSoil_ens)
matplot(years, t(cSoil_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'cSoil',
        bty = 'n')
matlines( years, t((cSoil_ens[toplevel_to_level_1a_ix, ])[level2_ix, ]),col = overplotcol,  lwd = 1.5, lty = 'solid')

ylim = range(cSoil_ens)
matplot(years, t(cVeg_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'cVeg',
        bty = 'n')
matlines( years, t((cVeg_ens[toplevel_to_level_1a_ix, ])[level2_ix, ]), col = overplotcol, lwd = 1.5, lty = 'solid')



ylim = range(cSoil_ens_anom)
matplot(years, t(cSoil_ens_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'cSoil Anomaly',
        bty = 'n')
matlines( years, t((cSoil_ens_anom[toplevel_to_level_1a_ix, ])[level2_ix, ]),col = overplotcol, lwd = 1.5, lty = 'solid')


ylim = range(cSoil_ens_anom)
matplot(years, t(cVeg_ens_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'cVeg Anomaly',
        bty = 'n')
matlines( years, t((cVeg_ens_anom[toplevel_to_level_1a_ix, ])[level2_ix, ]),col = overplotcol,lwd = 1.5, lty = 'solid')

5.3 Total land carbon change

We plot the JULES total land carbon change from 1850, together with “observations” from the Global Carbon Budget (Friedligstein et al, 2020). The “observations are the cumulative sum of the ‘land sink’ column on the”historical observations tab of the data from the paper. It states “The land sink is the average of several dynamic global vegetation models that reproduce the observed mean total land sink of the 1990s.”


par(mfrow= c(1,2), las = 1)

ylim = range(total_land_carbon_ens)
matplot(years, t(total_land_carbon_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Total land carbon',
        bty = 'n')
matlines( years, t((total_land_carbon_ens[toplevel_to_level_1a_ix, ])[level2_ix, ]), col = overplotcol, lty = 'solid', lwd = 1.5)

ylim = range(total_land_carbon_anom)
matplot(years, t(total_land_carbon_anom), type = 'l', lty = 'solid',ylim = ylim, col = plotcol,
        ylab = 'GtC', main = 'Total land carbon anomaly',
        bty = 'n')
matlines( years, t((total_land_carbon_anom[toplevel_to_level_1a_ix, ])[level2_ix, ]), col = overplotcol, lty = 'solid', lwd = 1.5)

#Anomalize historical observations to 1850 - 1870
historical_total_land_carbon_obs <- cumsum(historical_carbon_budget$`land sink`)
historical_total_land_carbon_obs_anom <- historical_total_land_carbon_obs - historical_total_land_carbon_obs[which(historical_carbon_budget$Year %in% 1850:1870)]

lines(historical_carbon_budget$Year,historical_total_land_carbon_obs_anom, type = 'l',col = 'blue', lwd = 2)
legend('topleft', legend = c('Ruled out', 'Level1a constraint', 'historical'), col = c('black', overplotcol, 'blue'),
       lwd = c(1,1.5,2), lty = 'solid')

NA
NA

5.3.1 Land carbon Sink?

I think to make a fair comparison, we might need to take the diff of the anomaly (or just the timeseries), as the above represents the total change since 1850, and I think all the “land sink” stuff looks at the year-to-year changes.



landsink_ens <- matrix(NA, nrow = nrow(total_land_carbon_ens), ncol = ncol(total_land_carbon_ens)-1)

for(i in 1:nrow(landsink_ens)){
  
  landsink_ens[i, ] <- diff(total_land_carbon_ens[i, ])
}


ylim = range(landsink_ens)
matplot(years[-1], t(landsink_ens), type = 'l', lty = 'solid',ylim = ylim, col = plotcol, xlab = '',
        ylab = 'GtC/year', main = 'Total land carbon sink',
        bty = 'n')
matlines( years[-1], t((landsink_ens[toplevel_to_level_1a_ix, ])[level2_ix, ]), col = 'tomato3', lty = 'solid')

lines(historical_carbon_budget$Year, historical_carbon_budget$`land sink`, col = 'blue', lwd = 2, xlab = '')
legend('bottomleft', legend = c('Ruled out','level 1a constrained','historical'), col = c('black','tomato3', 'blue' ), lty ='solid',
       lwd = c(1,1,2))

NA
NA

5.3.2 Identify parts of parameter space where the land carbon sink is at its maximum

What do these parts of parameter space tell us about what we need to do to have the model reproduce reality?


#Y.target = c(cs_gb.target, cv.target, npp_n_gb.target, runoff.target, nbp.target)

ynames_const <- c('nbp_lnd_sum', 'npp_nlim_lnd_sum', 'cSoil_lnd_sum', 'cVeg_lnd_sum')
yunits_const <- c('GtC/year', 'GtC/year', 'GtC', 'GtC')
Y_const_level1a <- Y_level1a[, ynames_const]

scalevec <- c(1e12/ysec, 1e12/ysec, 1e12, 1e12)
Y_const_level1a_scaled <- sweep(Y_const_level1a, 2, STATS = scalevec, FUN = '/' )

# This is a "normalisation vector", for making the output numbers more manageable.
#cs_gb       cv    gpp_gb        nbp npp_n_gb    runoff
norm_vec = c(1e12, 1e12, 1e12/ysec , 1e12, 1e12, 1e9)

# nbp  npp  csoil  cveg
Y_lower <- c(-10, 35, 750, 300)
Y_upper <- c(10, 80, 3000, 800)

# I'm going to set it so that + 4sd aligns approximately with the original limits
# given by Andy Wiltshire. This gives room for uncertainty from the emulator
Y_target = Y_upper - (abs(Y_upper - (Y_lower)) / 2 )# abs() to fix the problem with negative numbers


# standard deviation is derived from the limits and the central target
# (this distance is assumed to be 4 standard deviations.
Y_sd = (Y_upper - Y_target) / 4
names(Y_sd) = colnames(Y_const_level1a_scaled)


p = ncol(Y_const_level1a_scaled)

obs_sd_list = as.list(rep(0.01,p))
disc_list =  as.list(rep(0,p)) 
disc_sd_list =  as.list(Y_sd)
thres = 3

mins_aug = apply(X_level1a, 2, FUN = min)
maxes_aug =apply(X_level1a, 2, FUN = max)

# convert Y_target for ingestion into function
Y_target = matrix(Y_target, nrow = 1)

# Histogram of level 1 constraints
hcol = 'darkgrey'
lcol = 'black'
par(mfrow = c(2,2), fg = 'darkgrey', las = 1)



hist(Y_const_level1a_scaled[,'nbp_lnd_sum'], col = hcol, main = 'NBP', xlab = 'GtC/year')
polygon(x = c(-10, 100, 100, -10), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
        border = makeTransparent('tomato2'))

hist(Y_const_level1a_scaled[,'npp_nlim_lnd_sum'], col = hcol , main = 'NPP', xlab = 'GtC/year')
polygon(x = c(35, 80, 80, 35), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
        border = makeTransparent('tomato2'))

        hist(Y_const_level1a_scaled[,'cSoil_lnd_sum'], col = hcol, main = 'Soil Carbon', xlab = 'GtC')
polygon(x = c(750, 3000, 3000, 750), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
        border = makeTransparent('tomato2'))

hist(Y_const_level1a_scaled[,'cVeg_lnd_sum'], col = hcol, main = 'Vegetation Carbon', xlab = 'GtC')
polygon(x = c(300, 800, 800, 300), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
       border =  makeTransparent('tomato2'))


# remove to level 1a Relative to toplevel_ix
toplevel_to_level_1a_ix <-(toplevel_ix[-Y_nlevel0_ix])[level1a_ix]

# So further constraining to level 2 can be associated back to the top level.

level2_ix = which(Y_const_level1a_scaled[,'nbp_lnd_sum'] > -10 &
                    Y_const_level1a_scaled[,'npp_nlim_lnd_sum'] > 35 &  Y_const_level1a_scaled[,'npp_nlim_lnd_sum'] < 80 &
                    Y_const_level1a_scaled[,'cSoil_lnd_sum'] > 750 & Y_const_level1a_scaled[,'cSoil_lnd_sum'] < 3000 &
                  Y_const_level1a_scaled[,'cVeg_lnd_sum'] > 300 & Y_const_level1a_scaled[,'cVeg_lnd_sum'] < 800
  )

# Build an emulator for total land carbon uptake at the end of the century


# ensemble of modern landsink
landsink_modern_ix <- which(years[-1] %in% 1994:2013)

landsink_modern_ens <- (apply(landsink_ens[, landsink_modern_ix], 1, mean))


# observations of modern land sink

hist_ix <- which(historical_carbon_budget$Year %in% 1994:2013)
landsink_modern_obs <- mean(historical_carbon_budget$`land sink`[hist_ix ])

# This is all 499 members
landsink_modern_err <- landsink_modern_ens - landsink_modern_obs

landsink_modern_err_level1a <- landsink_modern_err[toplevel_to_level_1a_ix]#



#[level2_ix, ]

# Build emulators 

# Identify the parts of parameter space where the differences are low


# Are we getting close for the right reasons? What else is going wrong?

5.3.3 what parts of parameter space are the closest?



par(mfrow = c(4,8), mar = c(3,2,2,1))
for(i in 1:d){
  
  plot(X_level1a[, i],landsink_modern_err_level1a, )
  
}

NA
NA


fit_landsink_err <- km(~.,design = X_level1a, response =  landsink_modern_err_level1a)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -105.3316 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       105.33  |proj g|=       1.7763
At iterate     1  f =       104.53  |proj g|=        1.6751
At iterate     2  f =       100.62  |proj g|=        1.4962
At iterate     3  f =       98.816  |proj g|=        1.7742
At iterate     4  f =       97.817  |proj g|=        1.4271
At iterate     5  f =       96.597  |proj g|=        1.5206
At iterate     6  f =         94.6  |proj g|=          1.65
At iterate     7  f =       93.132  |proj g|=        1.8704
At iterate     8  f =       88.072  |proj g|=        1.7725
At iterate     9  f =       87.267  |proj g|=        1.6414
At iterate    10  f =       85.706  |proj g|=        1.4582
At iterate    11  f =        84.78  |proj g|=        1.3998
At iterate    12  f =        84.03  |proj g|=        1.1195
At iterate    13  f =       83.553  |proj g|=        1.6739
At iterate    14  f =       83.191  |proj g|=        1.0929
At iterate    15  f =       82.995  |proj g|=        1.0632
At iterate    16  f =       82.302  |proj g|=        1.4633
At iterate    17  f =       82.075  |proj g|=       0.86198
At iterate    18  f =       81.591  |proj g|=       0.71824
At iterate    19  f =       81.455  |proj g|=       0.46283
At iterate    20  f =       81.404  |proj g|=       0.42424
At iterate    21  f =       81.218  |proj g|=       0.51844
At iterate    22  f =       81.171  |proj g|=        1.6242
At iterate    23  f =       81.147  |proj g|=       0.41785
At iterate    24  f =       81.133  |proj g|=       0.37589
At iterate    25  f =       81.102  |proj g|=        0.5201
At iterate    26  f =       81.071  |proj g|=       0.39852
At iterate    27  f =       81.042  |proj g|=       0.39513
At iterate    28  f =       81.028  |proj g|=       0.20922
At iterate    29  f =       81.026  |proj g|=       0.13888
At iterate    30  f =       81.019  |proj g|=       0.22736
At iterate    31  f =       81.013  |proj g|=       0.30157
At iterate    32  f =           81  |proj g|=       0.42243
At iterate    33  f =       80.992  |proj g|=       0.26538
At iterate    34  f =       80.987  |proj g|=       0.19665
At iterate    35  f =       80.984  |proj g|=       0.26379
At iterate    36  f =       80.982  |proj g|=       0.17344
At iterate    37  f =       80.979  |proj g|=       0.38048
At iterate    38  f =        80.97  |proj g|=       0.71058
At iterate    39  f =       80.962  |proj g|=       0.43608
At iterate    40  f =       80.957  |proj g|=       0.20584
At iterate    41  f =       80.955  |proj g|=       0.23125
At iterate    42  f =       80.954  |proj g|=       0.18816
At iterate    43  f =       80.953  |proj g|=       0.33499
At iterate    44  f =       80.952  |proj g|=      0.094717
At iterate    45  f =       80.952  |proj g|=      0.048754
At iterate    46  f =       80.952  |proj g|=      0.046396
At iterate    47  f =       80.951  |proj g|=      0.098753
At iterate    48  f =        80.95  |proj g|=      0.080994
At iterate    49  f =       80.949  |proj g|=       0.37884
At iterate    50  f =       80.948  |proj g|=      0.084042
At iterate    51  f =       80.947  |proj g|=      0.062484
At iterate    52  f =       80.946  |proj g|=       0.11765
At iterate    53  f =       80.945  |proj g|=       0.17239
At iterate    54  f =       80.944  |proj g|=      0.088964
At iterate    55  f =       80.942  |proj g|=       0.11693
At iterate    56  f =        80.94  |proj g|=       0.17136
At iterate    57  f =       80.938  |proj g|=       0.18586
At iterate    58  f =       80.937  |proj g|=      0.048801
At iterate    59  f =       80.937  |proj g|=      0.032499
At iterate    60  f =       80.937  |proj g|=      0.057869
At iterate    61  f =       80.937  |proj g|=      0.086366
At iterate    62  f =       80.936  |proj g|=      0.050552
At iterate    63  f =       80.936  |proj g|=        0.0452
At iterate    64  f =       80.936  |proj g|=      0.041857
At iterate    65  f =       80.936  |proj g|=       0.11762
At iterate    66  f =       80.936  |proj g|=      0.036882
At iterate    67  f =       80.936  |proj g|=       0.01985
At iterate    68  f =       80.936  |proj g|=      0.027425
At iterate    69  f =       80.935  |proj g|=       0.03622
At iterate    70  f =       80.935  |proj g|=      0.074419
At iterate    71  f =       80.935  |proj g|=      0.023301
At iterate    72  f =       80.935  |proj g|=      0.024319
At iterate    73  f =       80.935  |proj g|=      0.020644
At iterate    74  f =       80.935  |proj g|=      0.074316
At iterate    75  f =       80.935  |proj g|=      0.033345
At iterate    76  f =       80.935  |proj g|=      0.014117
At iterate    77  f =       80.935  |proj g|=      0.012839
At iterate    78  f =       80.935  |proj g|=      0.090801
At iterate    79  f =       80.935  |proj g|=      0.016325
At iterate    80  f =       80.935  |proj g|=      0.010319
At iterate    81  f =       80.935  |proj g|=      0.006214
At iterate    82  f =       80.935  |proj g|=     0.0088201
At iterate    83  f =       80.935  |proj g|=     0.0063239
At iterate    84  f =       80.935  |proj g|=     0.0033038
At iterate    85  f =       80.935  |proj g|=     0.0029901
At iterate    86  f =       80.935  |proj g|=     0.0061585
At iterate    87  f =       80.935  |proj g|=     0.0015403
At iterate    88  f =       80.935  |proj g|=     0.0011796

iterations 88
function evaluations 99
segments explored during Cauchy searches 96
BFGS updates skipped 0
active bounds at final generalized Cauchy point 18
norm of the final projected gradient 0.0011796
final function value 80.9348

F = 80.9348
final  value 80.934787 
converged

plot(fit_landsink_err)

5.4 Augment the design.

The function addNroyDesignPoints builds an emulator for each model output in Y. It compares the output of each emulator at a number of candidate desin points, and chooses a space-filling set of them that that are Not Ruled Out Yet (statistically close to the observation at Y_target).


# Two strategies - plot land sink error against parameters, and identify bits of parameter space with smallest error

#low_error_ix <- landsink_modern_err_level1a


mins <- apply(X_level1a,2,FUN = min)
maxes <- apply(X_level1a,2,FUN = max)
  
nsamp_unif <- 100000  
X_unif <- samp_unif(nsamp_unif, mins = mins, maxes = maxes)

pred_unif <- predict(fit_landsink_err, newdata = X_unif, type = 'UK')

5.5 Write the augmented design

The function write_jules_design here simply takes the points calculated by addNroyDesignPoints and writes them to configuration files.



par(oma = c(0,0,0,3), bg = 'white')
pairs(X_level1a,
      labels = 1:d,
      gap = 0, lower.panel = NULL, xlim = c(0,1), ylim = c(0,1),
      panel = cpoints,
      z= landsink_modern_ens_level1a,
      col = byr,
      cex.labels = 1,
      col.axis = 'white',
      pch = 20
      )


#image.plot(legend.only = TRUE,
#           zlim = c(0,1),
#           col = blues,
#           legend.args = list(text = 'Density of model runs matching the criteria', side = 3, line = 1),
#           horizontal = TRUE
#)

#  legend('left', legend = paste(1:d, colnames(lhs)), cex = 0.9, bty = 'n')


X_kept <- X_unif[abs(pred_unif$mean) < 1, ] 

par(oma = c(0,0,0,3), bg = 'white')
pairs(X_kept,
      labels = 1:d,
      gap = 0, lower.panel = NULL, xlim = c(0,1), ylim = c(0,1),
      panel = dfunc_up,
      cex.labels = 1,
      col.axis = 'white',
      dfunc.col = blues)

image.plot(legend.only = TRUE,
           zlim = c(0,1),
           col = blues,
           legend.args = list(text = 'Density of model runs matching the criteria', side = 3, line = 1),
           horizontal = TRUE
)

legend('left', legend = paste(1:d, colnames(lhs)), cex = 0.9, bty = 'n')

NA
NA
NA
NA
NA

5.6 Check the design

Check that the augmented design produces what we expect. New ensemble members should be somewhat constrained within the boundaries of the original design, if the comparison to data offers any constraint.

# Final output needs to be expressed in terms of original LHS, then put back out to conf files.

# This function adds n.aug potential design points, and finds their implausibility
# score in X.nroy

wave1 = addNroyDesignPoints(X = X_level1a, 
                            Y = Y_const_level1a_scaled, 
                            Y_target = Y_target,
                            n_aug = 50000, 
                            mins_aug = mins_aug,
                            maxes_aug = maxes_aug,
                            thres = 3,
                            disc_list=disc_list,
                            disc_sd_list = disc_sd_list,
                            obs_sd_list = obs_sd_list,
                            n_app = 500,
                            nreps = 500)

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -109.2909 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       109.29  |proj g|=        1.871
At iterate     1  f =       100.41  |proj g|=        1.3975
At iterate     2  f =       96.533  |proj g|=        1.3088
At iterate     3  f =       95.227  |proj g|=        1.2724
At iterate     4  f =       92.512  |proj g|=        1.5964
At iterate     5  f =       91.143  |proj g|=        1.7368
At iterate     6  f =       89.279  |proj g|=        1.6991
At iterate     7  f =       88.195  |proj g|=        1.7046
At iterate     8  f =       87.014  |proj g|=        1.5114
At iterate     9  f =       85.689  |proj g|=        1.0118
At iterate    10  f =       85.023  |proj g|=        1.7091
At iterate    11  f =       84.569  |proj g|=        1.3563
At iterate    12  f =       84.158  |proj g|=       0.80825
At iterate    13  f =        84.09  |proj g|=        1.6904
At iterate    14  f =       83.823  |proj g|=        1.6909
At iterate    15  f =        83.55  |proj g|=       0.81435
At iterate    16  f =       83.371  |proj g|=       0.96783
At iterate    17  f =       83.094  |proj g|=        1.1149
At iterate    18  f =       82.902  |proj g|=       0.63225
At iterate    19  f =       82.876  |proj g|=        1.6631
At iterate    20  f =       82.821  |proj g|=       0.47627
At iterate    21  f =       82.812  |proj g|=       0.44135
At iterate    22  f =       82.724  |proj g|=       0.87459
At iterate    23  f =       82.656  |proj g|=       0.80084
At iterate    24  f =       82.618  |proj g|=       0.37465
At iterate    25  f =       82.608  |proj g|=       0.27736
At iterate    26  f =       82.599  |proj g|=       0.18904
At iterate    27  f =       82.587  |proj g|=       0.29552
At iterate    28  f =       82.563  |proj g|=       0.53817
At iterate    29  f =       82.536  |proj g|=         0.389
At iterate    30  f =        82.52  |proj g|=       0.27542
At iterate    31  f =       82.509  |proj g|=       0.43571
At iterate    32  f =       82.496  |proj g|=       0.39767
At iterate    33  f =       82.472  |proj g|=       0.67351
At iterate    34  f =       82.447  |proj g|=        1.0541
At iterate    35  f =       82.426  |proj g|=       0.41252
At iterate    36  f =       82.407  |proj g|=       0.36104
At iterate    37  f =        82.39  |proj g|=       0.37105
At iterate    38  f =       82.352  |proj g|=       0.40153
At iterate    39  f =       82.345  |proj g|=       0.48576
At iterate    40  f =       82.338  |proj g|=       0.30354
At iterate    41  f =       82.333  |proj g|=       0.28668
At iterate    42  f =       82.321  |proj g|=       0.24732
At iterate    43  f =       82.309  |proj g|=       0.34561
At iterate    44  f =       82.295  |proj g|=       0.29314
At iterate    45  f =       82.283  |proj g|=        0.5463
At iterate    46  f =       82.269  |proj g|=       0.55403
At iterate    47  f =       82.266  |proj g|=       0.38142
At iterate    48  f =       82.264  |proj g|=       0.15815
At iterate    49  f =        82.26  |proj g|=       0.11062
At iterate    50  f =       82.258  |proj g|=        0.1582
At iterate    51  f =       82.255  |proj g|=       0.22033
At iterate    52  f =       82.254  |proj g|=       0.13105
At iterate    53  f =       82.253  |proj g|=       0.05804
At iterate    54  f =       82.253  |proj g|=       0.15167
At iterate    55  f =       82.253  |proj g|=      0.054998
At iterate    56  f =       82.252  |proj g|=       0.03075
At iterate    57  f =       82.252  |proj g|=      0.029696
At iterate    58  f =       82.252  |proj g|=      0.016543
At iterate    59  f =       82.252  |proj g|=      0.014205
At iterate    60  f =       82.252  |proj g|=      0.026848
At iterate    61  f =       82.252  |proj g|=      0.027097
At iterate    62  f =       82.252  |proj g|=      0.012538
At iterate    63  f =       82.252  |proj g|=      0.011962
At iterate    64  f =       82.252  |proj g|=      0.011229
At iterate    65  f =       82.252  |proj g|=       0.01993
At iterate    66  f =       82.252  |proj g|=      0.012827
At iterate    67  f =       82.252  |proj g|=      0.016769
At iterate    68  f =       82.252  |proj g|=      0.038307
At iterate    69  f =       82.252  |proj g|=       0.02021
At iterate    70  f =       82.252  |proj g|=       0.01395
At iterate    71  f =       82.252  |proj g|=      0.019049
At iterate    72  f =       82.252  |proj g|=      0.028594
At iterate    73  f =       82.252  |proj g|=      0.033337
At iterate    74  f =       82.252  |proj g|=      0.020535
At iterate    75  f =       82.252  |proj g|=     0.0075909
At iterate    76  f =       82.252  |proj g|=     0.0055178
At iterate    77  f =       82.252  |proj g|=      0.033389
At iterate    78  f =       82.252  |proj g|=     0.0071442
At iterate    79  f =       82.252  |proj g|=        0.0111
At iterate    80  f =       82.252  |proj g|=       0.01729
At iterate    81  f =       82.252  |proj g|=       0.01571
At iterate    82  f =       82.252  |proj g|=      0.029493
At iterate    83  f =       82.252  |proj g|=     0.0070285
At iterate    84  f =       82.252  |proj g|=     0.0084202
At iterate    85  f =       82.252  |proj g|=      0.012163
At iterate    86  f =       82.252  |proj g|=      0.089832
At iterate    87  f =       82.252  |proj g|=       0.03557
At iterate    88  f =       82.252  |proj g|=      0.010387
At iterate    89  f =       82.252  |proj g|=       0.02101
At iterate    90  f =       82.252  |proj g|=      0.017472
At iterate    91  f =       82.252  |proj g|=      0.025682
At iterate    92  f =       82.252  |proj g|=     0.0079639
At iterate    93  f =       82.252  |proj g|=     0.0073904
At iterate    94  f =       82.252  |proj g|=      0.018008
At iterate    95  f =       82.252  |proj g|=     0.0062852
At iterate    96  f =       82.252  |proj g|=     0.0046032
At iterate    97  f =       82.252  |proj g|=     0.0028965
At iterate    98  f =       82.251  |proj g|=     0.0083294
At iterate    99  f =       82.251  |proj g|=      0.004218
At iterate   100  f =       82.251  |proj g|=     0.0024721
At iterate   101  f =       82.251  |proj g|=     0.0026606
final  value 82.251495 
stopped after 101 iterations

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -1383.375 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       1383.4  |proj g|=       1.7664
At iterate     1  f =       1372.9  |proj g|=        1.6648
At iterate     2  f =       1364.8  |proj g|=        1.7747
At iterate     3  f =       1356.7  |proj g|=        1.8961
At iterate     4  f =       1350.1  |proj g|=        1.7144
At iterate     5  f =       1347.8  |proj g|=        1.6582
At iterate     6  f =       1341.7  |proj g|=         1.481
At iterate     7  f =       1337.6  |proj g|=        1.6235
At iterate     8  f =       1335.4  |proj g|=        1.4778
At iterate     9  f =         1334  |proj g|=       0.92855
At iterate    10  f =         1332  |proj g|=        1.5095
At iterate    11  f =       1330.6  |proj g|=        1.0917
At iterate    12  f =       1329.3  |proj g|=        1.2354
At iterate    13  f =       1328.5  |proj g|=       0.82781
At iterate    14  f =       1328.3  |proj g|=        0.9746
At iterate    15  f =       1328.1  |proj g|=       0.55288
At iterate    16  f =         1328  |proj g|=       0.39538
At iterate    17  f =       1327.8  |proj g|=       0.30206
At iterate    18  f =       1327.8  |proj g|=        1.4645
At iterate    19  f =       1327.8  |proj g|=       0.56521
At iterate    20  f =       1327.8  |proj g|=       0.21692
At iterate    21  f =       1327.8  |proj g|=       0.56111
At iterate    22  f =       1327.8  |proj g|=       0.51424
At iterate    23  f =       1327.8  |proj g|=       0.53842
At iterate    24  f =       1327.8  |proj g|=        0.1763
At iterate    25  f =       1327.7  |proj g|=       0.20315
At iterate    26  f =       1327.7  |proj g|=       0.14516
At iterate    27  f =       1327.7  |proj g|=      0.054732
At iterate    28  f =       1327.7  |proj g|=      0.084036
At iterate    29  f =       1327.7  |proj g|=      0.045267
At iterate    30  f =       1327.7  |proj g|=      0.046735
At iterate    31  f =       1327.7  |proj g|=       0.14927
At iterate    32  f =       1327.7  |proj g|=       0.11387
At iterate    33  f =       1327.7  |proj g|=      0.025094
At iterate    34  f =       1327.7  |proj g|=      0.018372
At iterate    35  f =       1327.7  |proj g|=      0.018539
At iterate    36  f =       1327.7  |proj g|=      0.017334
At iterate    37  f =       1327.7  |proj g|=      0.035245
At iterate    38  f =       1327.7  |proj g|=      0.016258
At iterate    39  f =       1327.7  |proj g|=     0.0075892
At iterate    40  f =       1327.7  |proj g|=      0.008652
At iterate    41  f =       1327.7  |proj g|=      0.023457

iterations 41
function evaluations 48
segments explored during Cauchy searches 62
BFGS updates skipped 0
active bounds at final generalized Cauchy point 20
norm of the final projected gradient 0.0234567
final function value 1327.74

F = 1327.74
final  value 1327.742870 
converged

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -2561.221 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       2561.2  |proj g|=       1.8661
At iterate     1  f =       2533.6  |proj g|=             2
At iterate     2  f =       2519.6  |proj g|=             2
At iterate     3  f =       2516.5  |proj g|=        1.9534
At iterate     4  f =       2510.4  |proj g|=        1.7867
At iterate     5  f =         2505  |proj g|=        1.6826
At iterate     6  f =       2501.5  |proj g|=         1.618
At iterate     7  f =       2494.2  |proj g|=        1.3844
At iterate     8  f =       2492.2  |proj g|=        1.6032
At iterate     9  f =       2491.3  |proj g|=         1.589
At iterate    10  f =       2488.9  |proj g|=          1.53
At iterate    11  f =       2487.5  |proj g|=        1.0728
At iterate    12  f =       2487.2  |proj g|=        1.0711
At iterate    13  f =         2487  |proj g|=        1.1027
At iterate    14  f =       2486.8  |proj g|=       0.47609
At iterate    15  f =       2486.8  |proj g|=       0.42024
At iterate    16  f =       2486.8  |proj g|=        1.2305
At iterate    17  f =       2486.8  |proj g|=       0.38381
At iterate    18  f =       2486.8  |proj g|=       0.22702
At iterate    19  f =       2486.8  |proj g|=       0.21667
At iterate    20  f =       2486.8  |proj g|=       0.17646
At iterate    21  f =       2486.7  |proj g|=         0.202
At iterate    22  f =       2486.7  |proj g|=       0.44121
At iterate    23  f =       2486.7  |proj g|=       0.16229
At iterate    24  f =       2486.7  |proj g|=      0.066349
At iterate    25  f =       2486.7  |proj g|=      0.018863
At iterate    26  f =       2486.7  |proj g|=      0.034152
At iterate    27  f =       2486.7  |proj g|=      0.043297
At iterate    28  f =       2486.7  |proj g|=      0.014902
At iterate    29  f =       2486.7  |proj g|=      0.016268
At iterate    30  f =       2486.7  |proj g|=      0.013669
At iterate    31  f =       2486.7  |proj g|=      0.021967

iterations 31
function evaluations 34
segments explored during Cauchy searches 54
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.0219674
final function value 2486.74

F = 2486.74
final  value 2486.744525 
converged

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~alpha_io + a_wl_io + bio_hum_cn + b_wl_io + dcatch_dlai_io + 
    dqcrit_io + dz0v_dh_io + f0_io + fd_io + g_area_io + g_root_io + 
    g_wood_io + gs_nvg_io + hw_sw_io + kaps_roth + knl_io + lai_max_io + 
    lai_min_io + lma_io + n_inorg_turnover + nmass_io + nr_io + 
    retran_l_io + retran_r_io + r_grow_io + rootd_ft_io + sigl_io + 
    sorp + tleaf_of_io + tlow_io + tupp_io + l_vg_soil
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -2315.205 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       2315.2  |proj g|=       1.9221
At iterate     1  f =       2314.2  |proj g|=        1.7645
At iterate     2  f =       2314.1  |proj g|=       0.74274
At iterate     3  f =       2313.9  |proj g|=        1.3088
At iterate     4  f =       2313.7  |proj g|=        1.9298
At iterate     5  f =       2313.5  |proj g|=        1.9378
At iterate     6  f =       2313.1  |proj g|=        1.9199
At iterate     7  f =         2312  |proj g|=        1.9412
At iterate     8  f =       2311.8  |proj g|=        1.9461
At iterate     9  f =       2310.4  |proj g|=        1.3481
At iterate    10  f =       2309.3  |proj g|=        1.2924
At iterate    11  f =       2308.7  |proj g|=         1.937
At iterate    12  f =       2308.3  |proj g|=        1.5008
At iterate    13  f =       2308.3  |proj g|=         1.216
At iterate    14  f =       2308.2  |proj g|=        1.8896
At iterate    15  f =       2308.1  |proj g|=        1.8935
At iterate    16  f =       2307.5  |proj g|=        1.9032
At iterate    17  f =         2307  |proj g|=        1.8988
At iterate    18  f =       2304.7  |proj g|=        1.0033
At iterate    19  f =       2303.6  |proj g|=        1.5714
At iterate    20  f =       2303.5  |proj g|=         1.917
At iterate    21  f =       2303.3  |proj g|=        1.9143
At iterate    22  f =       2303.2  |proj g|=        1.9086
At iterate    23  f =       2303.1  |proj g|=        1.8843
At iterate    24  f =       2302.9  |proj g|=       0.70255
At iterate    25  f =       2302.9  |proj g|=       0.68074
At iterate    26  f =       2302.9  |proj g|=        1.9109
At iterate    27  f =       2302.8  |proj g|=        1.7663
At iterate    28  f =       2302.8  |proj g|=       0.67488
At iterate    29  f =       2302.6  |proj g|=        1.0907
At iterate    30  f =       2302.3  |proj g|=        1.9095
At iterate    31  f =       2302.2  |proj g|=        1.9105
At iterate    32  f =         2302  |proj g|=        1.4736
At iterate    33  f =         2302  |proj g|=        1.4695
At iterate    34  f =       2301.8  |proj g|=          1.32
At iterate    35  f =       2301.7  |proj g|=          1.91
At iterate    36  f =       2301.7  |proj g|=        1.3149
At iterate    37  f =       2301.6  |proj g|=       0.83873
At iterate    38  f =       2301.5  |proj g|=       0.96389
At iterate    39  f =       2301.5  |proj g|=        1.3464
At iterate    40  f =       2301.4  |proj g|=       0.53138
At iterate    41  f =       2301.3  |proj g|=        1.8834
At iterate    42  f =       2301.3  |proj g|=       0.82272
At iterate    43  f =       2301.3  |proj g|=       0.75558
At iterate    44  f =       2301.3  |proj g|=        1.8803
At iterate    45  f =       2301.3  |proj g|=        1.8814
At iterate    46  f =       2301.3  |proj g|=        1.8812
At iterate    47  f =       2301.3  |proj g|=         1.881
At iterate    48  f =       2301.2  |proj g|=        1.3784
At iterate    49  f =       2301.2  |proj g|=       0.62431
At iterate    50  f =       2301.2  |proj g|=        1.9114
At iterate    51  f =       2301.2  |proj g|=        1.9123
At iterate    52  f =       2301.1  |proj g|=        1.9116
At iterate    53  f =       2301.1  |proj g|=       0.63241
At iterate    54  f =       2301.1  |proj g|=       0.28367
At iterate    55  f =       2301.1  |proj g|=       0.31082
At iterate    56  f =       2301.1  |proj g|=       0.62345
At iterate    57  f =       2301.1  |proj g|=         1.911
At iterate    58  f =       2301.1  |proj g|=        1.9119
At iterate    59  f =       2301.1  |proj g|=        1.9112
At iterate    60  f =         2301  |proj g|=       0.29321
At iterate    61  f =         2301  |proj g|=       0.31545
At iterate    62  f =         2301  |proj g|=       0.84934
At iterate    63  f =         2301  |proj g|=        1.8836
At iterate    64  f =         2301  |proj g|=        1.8821
At iterate    65  f =         2301  |proj g|=       0.58887
At iterate    66  f =         2301  |proj g|=        1.2003
At iterate    67  f =         2301  |proj g|=       0.43465
At iterate    68  f =         2301  |proj g|=       0.42034
At iterate    69  f =         2301  |proj g|=       0.60752
At iterate    70  f =         2301  |proj g|=        1.6659
At iterate    71  f =         2301  |proj g|=        1.8816
At iterate    72  f =       2300.9  |proj g|=        1.8816
At iterate    73  f =       2300.9  |proj g|=        1.8828
At iterate    74  f =       2300.9  |proj g|=        1.8811
At iterate    75  f =       2300.9  |proj g|=       0.40944
At iterate    76  f =       2300.9  |proj g|=       0.36834
At iterate    77  f =       2300.9  |proj g|=       0.74183
At iterate    78  f =       2300.9  |proj g|=        1.6322
At iterate    79  f =       2300.9  |proj g|=         1.914
At iterate    80  f =       2300.9  |proj g|=        1.9141
At iterate    81  f =       2300.9  |proj g|=        1.9155
At iterate    82  f =       2300.9  |proj g|=        1.1075
At iterate    83  f =       2300.8  |proj g|=       0.97412
At iterate    84  f =       2300.8  |proj g|=       0.96614
At iterate    85  f =       2300.8  |proj g|=        1.8816
At iterate    86  f =       2300.8  |proj g|=        1.8815
At iterate    87  f =       2300.8  |proj g|=        1.9143
At iterate    88  f =       2300.7  |proj g|=       0.61654
At iterate    89  f =       2300.7  |proj g|=       0.61993
At iterate    90  f =       2300.7  |proj g|=       0.61744
At iterate    91  f =       2300.7  |proj g|=       0.59652
At iterate    92  f =       2300.7  |proj g|=       0.47719
At iterate    93  f =       2300.7  |proj g|=       0.53494
At iterate    94  f =       2300.7  |proj g|=       0.53394
At iterate    95  f =       2300.7  |proj g|=       0.52042
At iterate    96  f =       2300.7  |proj g|=       0.60048
At iterate    97  f =       2300.7  |proj g|=        1.9142
At iterate    98  f =       2300.7  |proj g|=        1.9152
At iterate    99  f =       2300.6  |proj g|=        1.9161
At iterate   100  f =       2300.6  |proj g|=        1.9168
At iterate   101  f =       2300.6  |proj g|=        1.3656
final  value 2300.595796 
stopped after 101 iterations

Visualise the predicted outputs at the NROY points of the old design, and the new suggested design.


# this needs sorting
source('~/myRpackages/julesR/vignettes/default_jules_parameter_perturbations.R')

# Easiest way to generate a design of the right size is to have a "fac" which takes
# the names from the parameter list, and then multiplies everything by 0.5 or 2

tf <- 'l_vg_soil'
# we don't want anything that is TRUE/FALSE to be in fac
fac_init <- names(paramlist)
not_tf_ix <- which(names(paramlist)!=tf)
paramlist_trunc <-paramlist[not_tf_ix]

fac <- names(paramlist_trunc)

maxfac <-lapply(paramlist_trunc,function(x) x$max[which.max(x$max)] / x$standard[which.max(x$max)])
minfac <- lapply(paramlist_trunc,function(x) x$min[which.max(x$max)] / x$standard[which.max(x$max)])

5.7 Visualising the emulated outputs at the proposed new design points.

Interestingly, these aren’t perfectly within the original hard boundaries set by Andy, even though I’ve set those boundaries to be the +- 4 standard deviation threholds in the History Match. I suggest this is because there is model discrepancy, and that there is considerable wriggle room induced from emulator uncertainty.

In particular, it appears that vegetation carbon is difficult to keep high, and that many NROY proposed members have a fairly low vegetation carbon. This might need a discrepancy term, or adjusting in some other way. It certainly needs exploring, and a OAAT plot might give clues as to the parameters to choose.

# create a directory for the configuration files
confdir <- 'conf_files_augment_JULES-ES-1p0'

dir.create(confdir)

X_mm <- wave1$X_mm

# This is the function that writes the configuration files.
write_jules_design(X_mm = X_mm, paramlist=paramlist, n = nrow(X_mm),
                    fac = fac, minfac = minfac, maxfac = maxfac,
                    tf = tf,
                    fnprefix = paste0(confdir,'/param-perturb-P'),
                    lhsfn = paste0(confdir,'/lhs_example.txt'),
                    stanfn = paste0(confdir,'/stanparms_example.txt'),
                    allstanfn = paste0(confdir,'/allstanparms_example.txt'),
                    rn = 12,
                    startnum = 500)

How good are the four emulators that we’ve built? Are there biases? (there’s no real evidence of this)



X_mm <- wave1$X_mm

pairs(rbind(X, X_mm), xlim = c(0,1), ylim = c(0,1), gap = 0, lower.panel = NULL, 
      col = c(rep('grey', nrow(X)), rep('red', nrow(X_mm))),
      pch = c(rep(21, nrow(X)), rep(20, nrow(X_mm)))
      )

par(xpd = NA)

legend('bottom',
       legend = c('Original design', 'New points'),
       col = c('grey', 'red'),
       inset = 0.15,
       cex = 1.5,
       pch = c(21,20)
)

5.8 One-at-a-time sensitivity analysis for understanding model response

It’s obviously hard to maintain a high vegetation carbon in particular. What parameter values might you choose to do this, and what might be the trade-offs you have to make?

Y_mm_list <- vector(mode ='list', length = length(wave1$fit_list))

for(i in 1:length(wave1$fit_list)){

y_mm <- predict(object=wave1$fit_list[[i]], newdata = wave1$X_mm, type = 'UK')

Y_mm_list[[i]] <- y_mm

}

First, what parameters affect vegetation carbon and how? How sure are we about that?

# Histogram of level 1 constraints
hcol = 'darkgrey'
lcol = 'black'
par(mfrow = c(2,2), fg = 'darkgrey', las = 1)

discsd <- c(disc_sd_list, recursive = TRUE)

hist(Y_const_level1a_scaled[,'nbp_lnd_sum'], col = hcol, main = 'NBP', xlab = 'GtC/year')
hist(Y_mm_list[[1]]$mean, add = TRUE, col = 'black')
polygon(x = c(-10, 100, 100, -10), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
        border = makeTransparent('tomato2'))
rug(Y_target[1], col = 'black')
rug(c(Y_target[1] + 3*discsd[1],Y_target[1] - 3*discsd[1]) , col = 'red')
some values will be clipped
hist(Y_const_level1a_scaled[,'npp_nlim_lnd_sum'], col = hcol , main = 'NPP', xlab = 'GtC/year')
hist(Y_mm_list[[2]]$mean, add = TRUE, col = 'black')
polygon(x = c(35, 80, 80, 35), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
        border = makeTransparent('tomato2'))
rug(Y_target[2], col = 'black')
rug(c(Y_target[2] + 3*discsd[2],Y_target[2] - 3*discsd[2]) , col = 'red')

hist(Y_const_level1a_scaled[,'cSoil_lnd_sum'], col = hcol, main = 'Soil Carbon', xlab = 'GtC')
hist(Y_mm_list[[3]]$mean, add = TRUE, col = 'black')
polygon(x = c(750, 3000, 3000, 750), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
        border = makeTransparent('tomato2'))
rug(Y_target[3], col = 'black')
rug(c(Y_target[3] + 3*discsd[3],Y_target[3] - 3*discsd[3]) , col = 'red')

hist(Y_const_level1a_scaled[,'cVeg_lnd_sum'], col = hcol, main = 'Vegetation Carbon', xlab = 'GtC')
hist(Y_mm_list[[4]]$mean, add = TRUE, col = 'black')
polygon(x = c(300, 800, 800, 300), y = c(0, 0, 1000, 1000),
        col = makeTransparent('tomato2'),
       border =  makeTransparent('tomato2'))
rug(Y_target[4], col = 'black')
rug(c(Y_target[4] + 3*discsd[4],Y_target[4] - 3*discsd[4]) , col = 'red')

NA

par(mfrow = c(2,2))

for(i in 1:4){
  
hist(wave1$pred_list[[i]]$mean, main = colnames(Y_const_level1a_scaled)[i])
  
}

NA
NA

What might be the trade-offs for a high (or accurate) vegetation carbon? are they acceptable? Plot the oaat sensitivity of the other 3 outputs we’re calibrating on.


X_oaat_level1a <- oaat_design(X_level1a, n=21, med = TRUE)
colnames(X_oaat_level1a) = colnames(X)

y_oaat <- predict.km(wave1$fit_list[[4]], newdata = X_oaat_level1a, type = 'UK')

What do the emulators make of the design points which actually make Andy’s “hard boundary” criteria? If we leave them out, do they still place the output within the hard boundaries?



oaatLinePlot(X_oaat = X_oaat_level1a, y_oaat_mean = y_oaat$mean, y_oaat_sd = y_oaat$sd, 
             n_oaat = 21,nr = 6, nc = 6) 

NA
NA

5.9 Check the emulators that produce the new design

Do a leave-one-out cross validation of points inside the hard boundaries using the wave1 fits.


Y_oaat_const_level1a_scaled <- matrix(ncol = ncol(Y_const_level1a_scaled), nrow = nrow(X_oaat_level1a))

for(i in 1:ncol(Y_const_level1a_scaled)){

  y_oaat <- predict.km(wave1$fit_list[[i]], newdata = X_oaat_level1a, type = 'UK')
  Y_oaat_const_level1a_scaled[,i] <- y_oaat$mean
}
Y_oaat_const_level1a_scaled_norm <- normalize(Y_oaat_const_level1a_scaled)

oaatLinePlotMulti(X_oaat = X_oaat_level1a, Y_oaat = Y_oaat_const_level1a_scaled_norm ,  n_oaat = 21, nr = 6, nc = 6,
                  lwd = 2)

reset()
legend('top', c('nbp', 'npp', 'csoil', 'cveg'), col = c(1,2,3,4), lty = 'solid', lwd = 2, horiz = TRUE)

NA
NA

We see in the leave-one-out analysis that the emulator is consistently under-predicting the vegetation carbon (though the uncertainty estimate often covers the actual value).This suggests (1) that there isn’t really a huge problem with a model discrepancy (or at least that isn’t the only problem), and (2) the history matching is working as it should, and taking into account a not-great emulator.


aw_boundary_ix = which(Y_const_level1a_scaled[,'nbp_lnd_sum'] > -10 &
                    Y_const_level1a_scaled[,'npp_nlim_lnd_sum'] > 35 &  Y_const_level1a_scaled[,'npp_nlim_lnd_sum'] < 80 &
                    Y_const_level1a_scaled[,'cSoil_lnd_sum'] > 750 & Y_const_level1a_scaled[,'cSoil_lnd_sum'] < 3000 &
                  Y_const_level1a_scaled[,'cVeg_lnd_sum'] > 300 & Y_const_level1a_scaled[,'cVeg_lnd_sum'] < 800
  )



X_aw_boundary = X_level1a[aw_boundary_ix, ]
Y_aw_boundary = Y_const_level1a_scaled[aw_boundary_ix, ]

5.10 Compare the straight km with a two-step emulator

Is a two-step emulator any better at emulating those crucial points which fall within aw’s hard boundaries? First, create a list of emulator fits.


fitlist_Y_const_level1a_scaled <- vector(mode = 'list', length = ncol(Y_const_level1a_scaled))

for(i in 1:ncol(Y_const_level1a_scaled)){
  
  y <- Y_const_level1a_scaled[,i]
  fit <- twoStep_glmnet(X = X_level1a, y)
  fitlist_Y_const_level1a_scaled[[i]] <- fit

}

loo_mean_Y_level1a <- matrix(nrow = nrow(X_level1a), ncol = ncol(Y_const_level1a_scaled))
loo_sd_Y_level1a <- matrix(nrow = nrow(X_level1a), ncol = ncol(Y_const_level1a_scaled))
  
  for(i in 1:ncol(Y_const_level1a_scaled)){

loo <- leaveOneOut.km(wave1$fit_list[[i]],type = 'UK', trend.reestim = TRUE )
  loo_mean_Y_level1a[,i] <- loo$mean
  loo_sd_Y_level1a[,i] <- loo$sd
}

It doesn’t appear that the two-step emulator (here plotted in red) is doing any better than the regular emulator.


par(mfrow = c(2,2))

for(i in 1:ncol(loo_mean_Y_level1a)){
  
  rn <- range(c(loo_mean_Y_level1a[aw_boundary_ix,i] - (2*loo_sd_Y_level1a[aw_boundary_ix,i]) , loo_mean_Y_level1a[aw_boundary_ix,i] + (2*loo_sd_Y_level1a[aw_boundary_ix,i]) ))
  
  
  
  plot(Y_const_level1a_scaled[aw_boundary_ix, i], loo_mean_Y_level1a[aw_boundary_ix,i], ylim = rn, main = colnames(Y_const_level1a_scaled)[i], xlab = 'actual', ylab = 'predicted')
  
  segments(x0 = Y_const_level1a_scaled[aw_boundary_ix, i], y0 = loo_mean_Y_level1a[aw_boundary_ix,i] - (2*loo_sd_Y_level1a[aw_boundary_ix,i])  , x1 = Y_const_level1a_scaled[aw_boundary_ix, i] , y1 = loo_mean_Y_level1a[aw_boundary_ix,i] + (2*loo_sd_Y_level1a[aw_boundary_ix,i]) , col = makeTransparent('black', 70))
  abline(0,1)
  
}

NA
NA

Two other things I can think of to check: 1) how about using “multistart” to choose different starting conditions for optimising the emulators and 2) Using a flat prior for the mean function rather than a linear prior.


fitlist_Y_const_level1a_scaled <- vector(mode = 'list', length = ncol(Y_const_level1a_scaled))

for(i in 1:ncol(Y_const_level1a_scaled)){
  
  y <- Y_const_level1a_scaled[,i]
  fit <- twoStep_glmnet(X = X_level1a, y)
  fitlist_Y_const_level1a_scaled[[i]] <- fit

}
Loading required package: Matrix

Attaching package: ‘Matrix’

The following object is masked from ‘package:spam’:

    det

Loaded glmnet 4.1-1
loo_mean_glmnet_Y_level1a <- matrix(nrow = nrow(X_level1a), ncol = ncol(Y_const_level1a_scaled))
loo_sd_glmnet_Y_level1a <- matrix(nrow = nrow(X_level1a), ncol = ncol(Y_const_level1a_scaled))
  
  for(i in 1:ncol(Y_const_level1a_scaled)){

loo <- leaveOneOut.km(fitlist_Y_const_level1a_scaled[[i]]$emulator,type = 'UK', trend.reestim = TRUE )
  loo_mean_glmnet_Y_level1a[,i] <- loo$mean
  loo_sd_glmnet_Y_level1a[,i] <- loo$sd
}
par(mfrow = c(2,2))

for(i in 1:ncol(loo_mean_Y_level1a)){
  
  rn <- range(c(loo_mean_Y_level1a[aw_boundary_ix,i] - (2*loo_sd_Y_level1a[aw_boundary_ix,i]) , loo_mean_Y_level1a[aw_boundary_ix,i] + (2*loo_sd_Y_level1a[aw_boundary_ix,i]) ))
  
  
  
  plot(Y_const_level1a_scaled[aw_boundary_ix, i], loo_mean_Y_level1a[aw_boundary_ix,i], ylim = rn, main = colnames(Y_const_level1a_scaled)[i], xlab = 'actual', ylab = 'predicted')
  
  points(Y_const_level1a_scaled[aw_boundary_ix, i], loo_mean_glmnet_Y_level1a[aw_boundary_ix,i], col = 'red')
  
  
  segments(x0 = Y_const_level1a_scaled[aw_boundary_ix, i], y0 = loo_mean_Y_level1a[aw_boundary_ix,i] - (2*loo_sd_Y_level1a[aw_boundary_ix,i])  , x1 = Y_const_level1a_scaled[aw_boundary_ix, i] , y1 = loo_mean_Y_level1a[aw_boundary_ix,i] + (2*loo_sd_Y_level1a[aw_boundary_ix,i]) , col = makeTransparent('black', 70))
  abline(0,1)
  
}

6 Exploring new constraints

Input from Eddy Robertson:

“We can assume that the majority of vegetation carbon is stored in tree trunks so, the carbon density of trees is approximately (cVeg_lnd_mean / treeFrac_lnd_mean). Although I suppose it’s possible that in the PPE the shrubs have become tree-like, so it might be interesting to plot cVeg_lnd_mean versus (shrubFrac_lnd_mean + treeFrac_lnd_mean) as well. The first question is whether cVeg_lnd_mean increases linearly with treeFrac_lnd_mean. Then if this turned out to be interesting, we could produce a treeCVeg_lnd_mean output.”


fitlist_flatprior_Y_const_level1a_scaled <- vector(mode = 'list', length = ncol(Y_const_level1a_scaled))

for(i in 1:ncol(Y_const_level1a_scaled)){
  
  y <- Y_const_level1a_scaled[,i]
  fit <- km(formula =~1, design = X_level1a, response = y)
  fitlist_flatprior_Y_const_level1a_scaled[[i]] <- fit

}

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~1
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -324.7357 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       324.74  |proj g|=       1.8894
At iterate     1  f =       154.68  |proj g|=             2
At iterate     2  f =       144.37  |proj g|=        1.9477
At iterate     3  f =       140.12  |proj g|=        1.8272
At iterate     4  f =       137.65  |proj g|=        1.5752
At iterate     5  f =       135.35  |proj g|=        1.4243
At iterate     6  f =       134.81  |proj g|=        1.1667
At iterate     7  f =       134.52  |proj g|=        1.0068
At iterate     8  f =       134.47  |proj g|=       0.55475
At iterate     9  f =       134.44  |proj g|=       0.37207
At iterate    10  f =       134.43  |proj g|=       0.20987
At iterate    11  f =       134.42  |proj g|=      0.076796
At iterate    12  f =       134.42  |proj g|=      0.026753
At iterate    13  f =       134.42  |proj g|=       0.01759
At iterate    14  f =       134.42  |proj g|=     0.0060535
At iterate    15  f =       134.42  |proj g|=     0.0041787
At iterate    16  f =       134.42  |proj g|=     0.0021465
At iterate    17  f =       134.42  |proj g|=       0.00377
At iterate    18  f =       134.42  |proj g|=      0.001123
At iterate    19  f =       134.42  |proj g|=    0.00021622

iterations 19
function evaluations 20
segments explored during Cauchy searches 42
BFGS updates skipped 0
active bounds at final generalized Cauchy point 19
norm of the final projected gradient 0.000216221
final function value 134.421

F = 134.421
final  value 134.420708 
converged

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~1
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -1621.762 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       1621.8  |proj g|=       1.7706
At iterate     1  f =       1507.2  |proj g|=        1.4766
At iterate     2  f =       1423.3  |proj g|=        1.7768
At iterate     3  f =       1418.6  |proj g|=        1.4019
At iterate     4  f =       1415.9  |proj g|=        1.6446
At iterate     5  f =       1415.3  |proj g|=        1.7139
At iterate     6  f =       1415.1  |proj g|=        1.6554
At iterate     7  f =       1414.8  |proj g|=        1.4108
At iterate     8  f =       1414.7  |proj g|=       0.99795
At iterate     9  f =       1414.5  |proj g|=       0.73402
At iterate    10  f =       1414.5  |proj g|=       0.66567
At iterate    11  f =       1414.5  |proj g|=       0.13919
At iterate    12  f =       1414.5  |proj g|=        0.0858
At iterate    13  f =       1414.5  |proj g|=      0.034268
At iterate    14  f =       1414.5  |proj g|=      0.063708
At iterate    15  f =       1414.5  |proj g|=      0.010821
At iterate    16  f =       1414.5  |proj g|=     0.0075671
At iterate    17  f =       1414.5  |proj g|=      0.012372
At iterate    18  f =       1414.5  |proj g|=     0.0071278
At iterate    19  f =       1414.5  |proj g|=     0.0036723

iterations 19
function evaluations 21
segments explored during Cauchy searches 70
BFGS updates skipped 0
active bounds at final generalized Cauchy point 25
norm of the final projected gradient 0.00367225
final function value 1414.5

F = 1414.5
final  value 1414.500017 
converged

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~1
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -2800.645 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=       2800.6  |proj g|=       1.8463
At iterate     1  f =       2616.7  |proj g|=        1.6218
At iterate     2  f =       2605.4  |proj g|=         1.553
At iterate     3  f =       2583.7  |proj g|=        1.6224
At iterate     4  f =       2577.2  |proj g|=         1.011
At iterate     5  f =         2573  |proj g|=        1.3781
At iterate     6  f =       2571.3  |proj g|=         1.308
At iterate     7  f =       2571.1  |proj g|=        0.9583
At iterate     8  f =         2571  |proj g|=       0.62272
At iterate     9  f =       2570.9  |proj g|=       0.44321
At iterate    10  f =       2570.9  |proj g|=       0.12021
At iterate    11  f =       2570.9  |proj g|=      0.055708
At iterate    12  f =       2570.9  |proj g|=      0.016351
At iterate    13  f =       2570.9  |proj g|=     0.0027779

iterations 13
function evaluations 16
segments explored during Cauchy searches 52
BFGS updates skipped 0
active bounds at final generalized Cauchy point 27
norm of the final projected gradient 0.00277786
final function value 2570.93

F = 2570.93
final  value 2570.925355 
converged

optimisation start
------------------
* estimation method   : MLE 
* optimisation method : BFGS 
* analytical gradient : used
* trend model : ~1
* covariance model : 
  - type :  matern5_2 
  - nugget : NO
  - parameters lower bounds :  1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 1e-10 
  - parameters upper bounds :  2 2 1.999244 1.698141 1.994798 1.990622 1.998154 1.778477 2 2 2 1.998084 2 2 2 1.99598 2 1.989889 1.997502 1.989483 1.98997 1.987916 1.983347 1.988424 2 1.990947 1.995643 1.994232 1.992247 2 2 2 
  - best initial criterion value(s) :  -2465.963 

N = 32, M = 5 machine precision = 2.22045e-16
At X0, 0 variables are exactly at the bounds
At iterate     0  f=         2466  |proj g|=       1.7876
At iterate     1  f =       2357.6  |proj g|=             2
At iterate     2  f =       2342.2  |proj g|=             2
At iterate     3  f =       2334.4  |proj g|=        1.9202
At iterate     4  f =       2331.2  |proj g|=        1.8804
At iterate     5  f =         2325  |proj g|=        1.7272
At iterate     6  f =         2322  |proj g|=        1.6469
At iterate     7  f =       2320.5  |proj g|=        1.4532
At iterate     8  f =       2317.5  |proj g|=        1.4216
At iterate     9  f =         2317  |proj g|=        1.3362
At iterate    10  f =       2316.1  |proj g|=        1.2141
At iterate    11  f =       2315.5  |proj g|=        1.1842
At iterate    12  f =       2315.4  |proj g|=       0.93199
At iterate    13  f =       2315.4  |proj g|=        0.5059
At iterate    14  f =       2315.4  |proj g|=       0.38256
At iterate    15  f =       2315.4  |proj g|=       0.53325
At iterate    16  f =       2315.4  |proj g|=       0.18709
At iterate    17  f =       2315.4  |proj g|=      0.038636
At iterate    18  f =       2315.4  |proj g|=       0.02819
At iterate    19  f =       2315.4  |proj g|=      0.033483
At iterate    20  f =       2315.4  |proj g|=      0.015972
At iterate    21  f =       2315.4  |proj g|=      0.014807
At iterate    22  f =       2315.4  |proj g|=     0.0076813
At iterate    23  f =       2315.4  |proj g|=     0.0071707

iterations 23
function evaluations 27
segments explored during Cauchy searches 50
BFGS updates skipped 0
active bounds at final generalized Cauchy point 21
norm of the final projected gradient 0.00717074
final function value 2315.38

F = 2315.38
final  value 2315.375074 
converged

Is the range of carbon densities narrower in the “hard boundary” set?

loo_mean_flatprior_Y_level1a <- matrix(nrow = nrow(X_level1a), ncol = ncol(Y_const_level1a_scaled))
loo_sd_flatprior_Y_level1a <- matrix(nrow = nrow(X_level1a), ncol = ncol(Y_const_level1a_scaled))
  
  for(i in 1:ncol(Y_const_level1a_scaled)){

loo <- leaveOneOut.km(fitlist_flatprior_Y_const_level1a_scaled[[i]],type = 'UK', trend.reestim = TRUE )
  loo_mean_flatprior_Y_level1a[,i] <- loo$mean
  loo_sd_flatprior_Y_level1a[,i] <- loo$sd
}
par(mfrow = c(2,2))

for(i in 1:ncol(loo_mean_Y_level1a)){
  
  rn <- range(c(loo_mean_Y_level1a[aw_boundary_ix,i] - (2*loo_sd_Y_level1a[aw_boundary_ix,i]) , loo_mean_Y_level1a[aw_boundary_ix,i] + (2*loo_sd_Y_level1a[aw_boundary_ix,i]) ))
  
  
  
  plot(Y_const_level1a_scaled[aw_boundary_ix, i], loo_mean_Y_level1a[aw_boundary_ix,i], ylim = rn, main = colnames(Y_const_level1a_scaled)[i], xlab = 'actual', ylab = 'predicted')
  
  points(Y_const_level1a_scaled[aw_boundary_ix, i], loo_mean_flatprior_Y_level1a[aw_boundary_ix,i], col = 'red')
  
  
  segments(x0 = Y_const_level1a_scaled[aw_boundary_ix, i], y0 = loo_mean_Y_level1a[aw_boundary_ix,i] - (2*loo_sd_Y_level1a[aw_boundary_ix,i])  , x1 = Y_const_level1a_scaled[aw_boundary_ix, i] , y1 = loo_mean_flatprior_Y_level1a[aw_boundary_ix,i] + (2*loo_sd_flatprior_Y_level1a[aw_boundary_ix,i]) , col = makeTransparent('black', 70))
  abline(0,1)
  
}

NA
NA
NA

6.1 Now that we have constraints, we can explore their effect on the output


#pdf(file = 'vegC_density.pdf', width = 6, height = 6)
plot(Y_level0[,'treeFrac_lnd_mean'],Y_level0[,'cVeg_lnd_mean'], main = "Vegetation (tree) carbon density, Level0",
     xlab = 'treeFrac_lnd_mean', ylab  = 'cVeg_lnd_mean' )


#dev.off()

6.2 How much does constraining an output constrain other outputs?

For example, what effect has the AW “hard boundary” constraint produced on ranges of the other (marginal) outputs? Which constraint is doing the majority of the work?

A function to find the proportion of output space that is removed (or retained) when applying a constraint.


Y_level1a_aw <- Y_level1a[aw_boundary_ix, ]
X_level1a_aw <- X_level1a[aw_boundary_ix, ]

#pdf(file = 'vegC_density_aw.pdf', width = 6, height = 6)
plot(Y_level1a[,'treeFrac_lnd_mean'],Y_level1a[,'cVeg_lnd_mean'], main = "Vegetation (tree) carbon density",
     xlab = 'treeFrac_lnd_mean', ylab  = 'cVeg_lnd_mean' )

points( Y_level1a_aw[,'treeFrac_lnd_mean'],Y_level1a_aw[,'cVeg_lnd_mean'], pch = 19, col = 'red')
legend('topleft', legend = c('Level1a','AW constraints'), pch = c(21, 19), col = c('black', 'red'))

#   dev.off()
c_density <- Y_level1a[,'treeFrac_lnd_mean'] / Y_level1a[,'cVeg_lnd_mean']

hist(c_density)

NA
NA
NA

All constraints together take the normalized range of all the outputs to a little under a half of the original range, on average. Of course, four of the inputs are constrained here, which has quite a large impact.

# Pairs plot of output
y_names_mean <- c('nbp_lnd_mean', 'fLuc_lnd_mean', 'npp_nlim_lnd_mean', 'cSoil_lnd_mean',
            'cVeg_lnd_mean', 'landCoverFrac_lnd_mean', 'fHarvest_lnd_mean',
            'lai_lnd_mean', 'rh_lnd_mean', 'treeFrac_lnd_mean', 'c3PftFrac_lnd_mean', 
            'c4PftFrac_lnd_mean', 'shrubFrac_lnd_mean', 'baresoilFrac_lnd_mean')

Y_level1a_mean <- Y_level1a[,y_names_mean]

pcol <- rep('black', nrow(Y_level1a_mean))
pcol[aw_boundary_ix] <- 'red'
pairs(Y_level1a_mean, col = pcol, lower.panel = NULL, pch = 19, cex.labels = 1.5)

NA
NA
NA
NA

We can see what impacts the constraints have individually


constraint_prop <- function(Y, constraint_ix){
  
  Yconst <- Y[constraint_ix, ]
  Yconst_norm <- normalize(Yconst, wrt = Y)
  rn <- apply(Yconst_norm, 2, range)
  out <- rn
  out
  
}

The NBP constraint has no marginal impact

Y_constraint_plot <- function(constraint_range, constraint_columns, ...){
  # A function to plot the output of constraint_prop
  
  par(mar = c(12,4,3,2),las = 2)

pcol = rep('black', ncol(constraint_range))
pcol[constraint_columns] <- 'red' # plot the outputs where we have specified the constraints in red.

plot(1:ncol(constraint_range),constraint_range[2,], ylim = c(0,1) , axes = FALSE, xlab = '', ylab = 'range of ensemble (fraction)', col = pcol, pch = 19, ...)
points(1:ncol(constraint_range), constraint_range[1,], col = pcol, pch = 19)
segments(x0 = 1:ncol(constraint_range), y0 = constraint_range[1,], x1 = 1:ncol(constraint_range), y1 = constraint_range[2,], col = pcol, lwd =2 )

axis(side = 1, labels = colnames(constraint_range), at = 1:ncol(constraint_range))
axis(2)
abline(h = c(0,1), col = 'red')
  
}
Y_level1a_mean_aw_norm_rn <- constraint_prop(Y = Y_level1a_mean, constraint_ix = aw_boundary_ix)
mean_constraint_all <- mean(Y_level1a_mean_aw_norm_rn[2, ] - Y_level1a_mean_aw_norm_rn[1, ])
Y_constraint_plot(Y_level1a_mean_aw_norm_rn,constraint_columns = c(c(1,3,4,5)), main = paste('mean constrained range =', round(mean_constraint_all,3)))


nbp_ix <- which(Y_const_level1a_scaled[,'nbp_lnd_sum'] > -10)
npp_ix <- which(Y_const_level1a_scaled[,'npp_nlim_lnd_sum'] > 35 &  Y_const_level1a_scaled[,'npp_nlim_lnd_sum'] < 80 )
cSoil_ix <- which(Y_const_level1a_scaled[,'cSoil_lnd_sum'] > 750 & Y_const_level1a_scaled[,'cSoil_lnd_sum'] < 3000)
cVeg_ix <- which(Y_const_level1a_scaled[,'cVeg_lnd_sum'] > 300 & Y_const_level1a_scaled[,'cVeg_lnd_sum'] < 800)

Vegetation carbon (cVeg) has the strongest impact on everything else. This is no suprise, given that so few of the ensemble members seem to simulate carbon vegetation high enough.


Y_level1a_mean_nbp_const <- constraint_prop(Y = Y_level1a_mean, constraint_ix = nbp_ix )
mean_constraint_nbp <- mean(Y_level1a_mean_nbp_const[2, ] - Y_level1a_mean_nbp_const[1, ])
Y_constraint_plot(Y_level1a_mean_nbp_const,1,  main = paste('mean constrained range =', round(mean_constraint_nbp,3)))


Y_level1a_mean_npp_const <- constraint_prop(Y = Y_level1a_mean, constraint_ix = npp_ix )
mean_constraint_npp <- mean(Y_level1a_mean_npp_const[2, ] - Y_level1a_mean_npp_const[1, ])
Y_constraint_plot(Y_level1a_mean_npp_const,3,  main = paste('mean constrained range =', round(mean_constraint_npp,3)))

6.3 Writing robust, parallelised, multistart emulators


Y_level1a_mean_cSoil_const <- constraint_prop(Y = Y_level1a_mean, constraint_ix = cSoil_ix )
mean_constraint_cSoil <- mean(Y_level1a_mean_cSoil_const[2, ] - Y_level1a_mean_cSoil_const[1, ])
Y_constraint_plot(Y_level1a_mean_cSoil_const,4,  main = paste('mean constrained range =', round(mean_constraint_cSoil,3)))

7 Direct twoStep emulator using foreach


Y_level1a_mean_cVeg_const <- constraint_prop(Y = Y_level1a_mean, constraint_ix = cVeg_ix )
mean_constraint_cVeg <- mean(Y_level1a_mean_cVeg_const[2, ] - Y_level1a_mean_cVeg_const[1, ])
Y_constraint_plot(Y_level1a_mean_cVeg_const,5,  main = paste('mean constrained range =', round(mean_constraint_cVeg,3)))


# I actually wrote code to do this createKmFitList, which isn't parallel at the moment.
# Maybe make it parallel in the next version?

library(doParallel)
registerDoParallel(cores = detectCores() - 1)

direct_twoStep_glmnet_parallel <- function(X, Y, ...){
  
  d <- ncol(Y)
  foreach(i = 1:d) %dopar% {
    
    y <- Y[,i]
    
    em <- twoStep_glmnet(X=X, y = y, ...)
  }
} 

library(doParallel)
cores=detectCores()
cl <- makeCluster(cores[1]-1) #not to overload your computer
registerDoParallel(cl)

fitlist_test <- createKmFitListParallel(X = X_level1a, Y =  Y_const_level1a_scaled, formula = ~., multistart = 4)
stopCluster(cl)


plot(fitlist_test[[4]])

#summariseKmLoo <- function(fit){
  
#  loo <- leaveOneOut.km(fit, type = 'UK', trend.reestim = TRUE)
  
#  loo_mean <- mean(loo$)
  
  
#}

# system.time(testloop <- direct_twoStep_glmnet(X=X_level1, Y_level1))
# Test parallel processing against a foreach processing (and maybe mclapply?)

#system.time(testloop_par <- direct_twoStep_glmnet_parallel(X=X_level1, Y_level1))
emList <- function(X, Y){
  # Create a list of objects to be emulated
  # X             design matrix with (nrow) instances of (ncol) inputs
  # Y             matrix of outputs, with one row
  #               for each row of X

  d <- ncol(Y)
  em_list <- vector(mode='list', length=d)

  for(i in 1:d){
    em_obj <- NULL
    em_obj$X <- X
    em_obj$y <- Y[, i]
    em_list[[i]] <- em_obj
  }
  em_list
}


#test <- emlist(X_level1, Y_level1)

#mclapply(X = test, FUN = km)

# function from hde for direct prediction
direct.pred = function (form, X, Y, Xnew, ...){
  # Directly applies km in parallel to predict each column of an ensemble
  ens.list = emlist(X = X, Y = Y)
  km.list = mclapply(ens.list, FUN = km.wrap, form = form)

  pred.list = mclapply(km.list, FUN = km.pred.wrap, Xnew = as.matrix(Xnew, nrow = 1), type = "UK")

  out.mean = sapply(pred.list, FUN=extract.predmean)
  out.sd = sapply(pred.list, FUN=extract.predsd)
  return(list(mean = out.mean, sd = out.sd))
}
LS0tCnRpdGxlOiAiU2Vuc2l0aXZpdHkgYW5hbHlzaXMgYW5kIGNvbnN0cmFpbnQgb2YgdGhlIHBhcmFtZXRlciBzcGFjZSBvZiBFYXJ0aCBTeXN0ZW0gY29uZmlndXJhdGlvbiBvZiBKVUxFUyIKYXV0aG9yOiAiRG91ZyBNY05lYWxsIgpkYXRlOiAiMjQvMDMvMjAyMSIKb3V0cHV0OiAKICAgIGh0bWxfbm90ZWJvb2s6CiAgICAgICAgdG9jOiB0cnVlCiAgICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgICAgdG9jX2RlcHRoOiAzCiAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3Rpb24KVXBkYXRlIG9mIGV4cGxvcmUtSlVMRVMtRVMtMXAwLlJtZCB0aGF0IHVzZXMgdGhlIG5ldyBwYWNrYWdlcyBhbmQgZnVuY3Rpb25zCgpXZSBidWlsZCBhbmQgdGVzdCBnYXVzc2lhbiBwcm9jZXNzIGVtdWxhdG9ycywgcGVyZm9ybSBhIHNlbnNpdGl2aXR5IGFuYWx5aXMsIGFuZCBjb25zdHJhaW4gdGhlIGlucHV0IHNwYWNlIG9mIEp1bGVzLgoKCkFuZHkgdGhpbmtzIHRoZXJlIG1pZ2h0IGJlIG1pbGVhZ2UgaW4gYW5hbHlzaW5nIHRoZSBhdG1vc3BoZXJpYyBncm93dGgsIHdoaWNoIGlzIGhlcmUuCi9ob21lL2gwMS9oYWRhdy9SZXNlYXJjaC9FU19QUEUvT2N0MjAKICAKQXQgdGhlIG1vbWVudCwgdGhpcyB2aWduZXR0ZSBpcyBoYW1wZXJlZCBieSB0aGUgZmFjdCB0aGF0IGVtdWxhdG9ycyBhcmUgZmFpbGluZyBvbiBhIGZldyBvZiB0aGUgb3V0cHV0cyB3aGljaCByZXByZXNlbnQgY2hhbmdlIG92ZXIgdGhlIGhpc3RvcmljYWwgcGVyaW9kLiBUaGUgZW11bGF0b3IgaXMgZmluZSBmb3IgcHJlZGljdGluZyBhYnNvbHV0ZSB2YWx1ZXMgaW4gdGhlIG1vZGVybiBwZXJpb2QuCgpBbmR5IHdvdWxkIGxpa2UgdG8gc2VlIHRpbWVzZXJpZXMgb2Y6CmNWZWcsIGNTb2lsIGFuZCBuYnAsIG5wcCBpbiBHdEMgYW5kIEd0Qy95ci4KCiMjIFByZWxpbWluYXJpZXMKTG9hZCBsaWJyYXJpZXMsIGZ1bmN0aW9ucyBhbmQgZGF0YS4KCmBgYHtyLCBlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExvYWQgaGVscGVyIGZ1bmN0aW9ucwoKa25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5wYXRoID0gImZpZ3MvIiwgZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZ3MgPSBGQUxTRSkKIyBsb2FkIHNvbWUgaGVscGVyIGZ1bmN0aW9ucwpzb3VyY2UoJ34vYnJhemlsQ1NTUC9jb2RlL2JyYXppbF9jc3NwL3Blcl9wZnQuUicpICMgZXZlbnR1YWxseSwgbW92ZSB0aGUgcmVsZXZhbnQgZnVuY3Rpb25zCnNvdXJjZSgnZXhwbG9yZS1KVUxFUy1FUy0xcDBfUFBFX2Z1bmN0aW9ucy5SJykKYGBgCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExvYWQgcGFja2FnZXMKCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KGZpZWxkcykKbGlicmFyeShNQVNTKQpsaWJyYXJ5KERpY2VLcmlnaW5nKQpsaWJyYXJ5KERpY2VFdmFsKQpsaWJyYXJ5KG5jZGY0KQpsaWJyYXJ5KG5jZGY0LmhlbHBlcnMpCmxpYnJhcnkocmVhZHhsKQoKbGlicmFyeShmb3JlYWNoKQoKbGlicmFyeShlbXRvb2xzKQpsaWJyYXJ5KGltcHRvb2xzKQpsaWJyYXJ5KHZpenRvb2xzKQpsaWJyYXJ5KGp1bGVzUikKCgpgYGAKCgpgYGB7cn0KIyBTb21lIHBhbGxldGUgb3B0aW9ucwp5ZyA9IGJyZXdlci5wYWwoOSwgIllsR24iKQpyeWIgPSBicmV3ZXIucGFsKDExLCAiUmRZbEJ1IikKYnlyID0gcmV2KHJ5YikKcmIgPSBicmV3ZXIucGFsKDExLCAiUmRCdSIpCmJyID0gcmV2KHJiKQpibHVlcyA9IGJyZXdlci5wYWwoOSwgJ0JsdWVzJykKY2JQYWwgPC0gYygiIzAwMDAwMCIsICIjRTY5RjAwIiwgIiM1NkI0RTkiLCAiIzAwOUU3MyIsICIjRjBFNDQyIiwgIiMwMDcyQjIiLCAiI0Q1NUUwMCIsICIjQ0M3OUE3IikKCnlzZWMgPSA2MCo2MCoyNCozNjUKeWVhcnMgPC0gMTg1MDoyMDEzCmBgYAoKIyMgQ2FyYm9uIGJ1ZGdldCBkYXRhCgpbU2VjdGlvbiAyLjUgaW4gRnJpZWRsaW5nc3RlaW4gZXQgYWwuXShodHRwczovL2Vzc2QuY29wZXJuaWN1cy5vcmcvYXJ0aWNsZXMvMTIvMzI2OS8yMDIwLyNzZWN0aW9uMikgZGVzY3JpYmVzIGhvdyB0aGUgbGFuZCBjYXJib24gc2luayBpcyBlc3RpbWF0ZWQuCmBgYHtyLCBoaXN0b3JpY2FsLWNhcmJvbi1idWRnZXQsIHdhcm5pbmcgPSBGQUxTRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDl9CgoKIyBRdWVzdGlvbjogSG93IGNsb3NlbHkgc2hvdWxkIG91ciBtb2RlbCBtYXRjaCB0aGlzIGN1cnZlPyBXaGljaCBvdXRwdXQ/CiMgKE15IGd1ZXNzIGlzICdUb3RhbCBMYW5kIENhcmJvbiBhbm9tYWx5JykKaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0IDwtIHJlYWRfZXhjZWwoJ0dsb2JhbF9DYXJib25fQnVkZ2V0XzIwMjB2MS4wLnhsc3gnLCBzaGVldCA9ICJIaXN0b3JpY2FsIEJ1ZGdldCIsIHNraXAgPSAxNSkKCnBhcihtZnJvdyA9IGMoMywxKSkKeWxpbSA9IGMoLTEsIDYpCgpwbG90KGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyLCBoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkYGxhbmQgc2lua2AsIHR5cGUgPSAnbCcsIGJ0eSA9ICduJywgeWxpbSA9IHlsaW0pCgpwbG90KGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyLCBoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkYGxhbmQtdXNlIGNoYW5nZSBlbWlzc2lvbnNgLCB0eXBlID0gJ2wnLCBidHkgPSAnbicsIHlsaW0gPSB5bGltKQoKcGxvdChoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBhdG1vc3BoZXJpYyBncm93dGhgLCB0eXBlID0gJ2wnLCBidHkgPSAnbicsIHlsaW0gPSB5bGltKQoKCgpgYGAKCgoKCiMjIyBKdWxlcyBvdXRwdXQgZGF0YSBsb2NhdGlvbgpgYGB7ciwgbG9hZC1vdXRwdXQtZW5zZW1ibGV9CgplbnNsb2MgPC0gJy9wcm9qZWN0L2NhcmJvbl9wcGUvSlVMRVMtRVMtMXAwX1BQRS8nCmVuc21lbWJlciA8LSAnUDAwMDAvJwpzdWJkaXIgPC0gJ3N0YXRzLycKCmZsb2MgPC0gcGFzdGUwKGVuc2xvYyxlbnNtZW1iZXIsc3ViZGlyKQpmbiA8LSAnSlVMRVMtRVMtMXAwX1AwMDAwX0FubnVhbF9nbG9iYWwubmMnCgojIHRlc3QgZmlsZQpuYyA8LSBuY19vcGVuKHBhc3RlMChmbG9jLGZuKSkKCiMgV2hhdCB2YXJpYWJsZXMgYXJlIGluIHRoZSBmaWxlPyAKdmFybGlzdCA8LSBuYy5nZXQudmFyaWFibGUubGlzdChuYykKCgpmb3IoaSBpbiAxOmxlbmd0aCh2YXJsaXN0KSl7CiAgCiAgdmFyIDwtIHZhcmxpc3RbaV0KICBwcmludCh2YXIpCiAgcHJpbnQobmNhdHRfZ2V0KG5jLHZhciwibG9uZ19uYW1lIilbWzJdXSkKfQpgYGAKCiMjIEV4dHJhY3QgYSB0aW1lIHNlcmllcyBvZiBhbiBhbm51YWwsIGdsb2JhbGx5IGFnZ3JlZ2F0ZWQgdmFyaWFibGUKYGBge3IsIGV4dGFyY3QtdGltZS1zZXJpZXN9CgpleHRyYWN0VGltZXNlcmllcyA8LSBmdW5jdGlvbihuYywgdmFyaWFibGUpewogICAgZGF0IDwtIG5jdmFyX2dldChuYywgdmFyaWFibGUpCiAgICBvdXQgPC0gZGF0CiAgICBvdXQKfQoKbWFrZVRpbWVzZXJpZXNFbnNlbWJsZSA8LSBmdW5jdGlvbih2YXJpYWJsZSwgbmVucyA9IDQ5OSwgbnRzID0gMTY0LCBjbiA9IDE4NTA6MjAxMyl7CiAgCiAgIyBuZW5zIGlzIG51bWJlciBvZiBlbnNlbWJsZSBtZW1iZXJzCiAgIyBudHMgbGVuZ3RoIG9mIHRpbWVzZXJpZXMKICAjIGNuIGlzIGNvbG5hbWVzKCkKICBkYXRtYXQgPC0gbWF0cml4KE5BLCBucm93ID0gbmVucywgbmNvbCA9IG50cykKICBjb2xuYW1lcyhkYXRtYXQpIDwtIGNuCiAgCiAgZW5zbGlzdCA8LSBwYXN0ZSgiUCIsIGZvcm1hdEMoMDoobmVucy0xKSwgd2lkdGg9NCwgZmxhZz0iMCIpLCBzZXA9IiIpCiAgZmxvYyA8LSBwYXN0ZTAoZW5zbG9jLGVuc21lbWJlcixzdWJkaXIpCiAgCiAgZm9yKGkgaW4gMTpuZW5zKXsKICAgIAogICAgdmVjIDwtIHJlcChOQSxudHMpCiAgICAKICAgIGVuc21lbWJlciA8LSBlbnNsaXN0W2ldIAogICAgCiAgICBmbiA8LSBwYXN0ZTAoZW5zbG9jLGVuc21lbWJlciwnL3N0YXRzLycsJ0pVTEVTLUVTLTFwMF8nLGVuc21lbWJlciwnX0FubnVhbF9nbG9iYWwubmMnKQogCiAgICAKICAgIHRyeShuYyA8LSBuY19vcGVuKHBhc3RlMChmbikpKQogICAgdHJ5KGRhdCA8LSBleHRyYWN0VGltZXNlcmllcyhuYywgdmFyaWFibGUpKQogICAgCiAgICBkYXRtYXRbaSwgXSA8LSBkYXQKICAgIG5jX2Nsb3NlKG5jKQogIH0KICBkYXRtYXQKfQoKYGBgCgoKIyMgUGxvdCB0aW1lc2VyaWVzIG9mIGFnZ3JlZ2F0ZWQgZ2xvYmFsIHRpbWVzZXJpZXMgCgpgYGB7ciBpbmNsdWRlPUZBTFNFLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KCiN5bmFtZXNfY29uc3QgPC0gYygnbmJwX2xuZF9zdW0nLCAnbnBwX25saW1fbG5kX3N1bScsICdjU29pbF9sbmRfc3VtJywgJ2NWZWdfbG5kX3N1bScpCiN5dW5pdHNfY29uc3QgPC0gYygnR3RDL3llYXInLCAnR3RDL3llYXInLCAnR3RDJywgJ0d0QycpCiNZX2NvbnN0X2xldmVsMSA8LSBZX2xldmVsMVssIHluYW1lc19jb25zdF0KCiMgcHJpbWFyeSBjYXJib24gY3ljbGUgb3V0cHV0cwpucHBfZW5zIDwtIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAibnBwX25saW1fbG5kX3N1bSIpIC8gKDFlMTIveXNlYykKbmJwX2VucyA8LSAgbWFrZVRpbWVzZXJpZXNFbnNlbWJsZSh2YXJpYWJsZSA9ICJuYnBfbG5kX3N1bSIpIC8gKDFlMTIveXNlYykKY1NvaWxfZW5zIDwtICBtYWtlVGltZXNlcmllc0Vuc2VtYmxlKHZhcmlhYmxlID0gImNTb2lsX2xuZF9zdW0iKSAvIDFlMTIKY1ZlZ19lbnMgPC0gIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAiY1ZlZ19sbmRfc3VtIikgLyAxZTEyCgp0b3RhbF9sYW5kX2NhcmJvbl9lbnMgPC0gY1NvaWxfZW5zICsgY1ZlZ19lbnMKCmxhaV9sbmRfbWVhbl9lbnMgPC0gbWFrZVRpbWVzZXJpZXNFbnNlbWJsZSh2YXJpYWJsZSA9ICJsYWlfbG5kX21lYW4iKQoKIyBmbHV4ZXMKcmhfbG5kX3N1bV9lbnMgPC0gbWFrZVRpbWVzZXJpZXNFbnNlbWJsZSh2YXJpYWJsZSA9ICJyaF9sbmRfc3VtIikgLyAoMWUxMi95c2VjKQpmTHVjX2xuZF9zdW1fZW5zIDwtIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAiZkx1Y19sbmRfc3VtIikgLyAoMWUxMi95c2VjKQpmSGFydmVzdF9sbmRfc3VtX2VucyA8LSBtYWtlVGltZXNlcmllc0Vuc2VtYmxlKHZhcmlhYmxlID0gImZIYXJ2ZXN0X2xuZF9zdW0iKSAvICgxZTEyL3lzZWMpCgoKIyBmcmFjdGlvbnMKdHJlZUZyYWNfbG5kX21lYW5fZW5zIDwtIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAidHJlZUZyYWNfbG5kX21lYW4iKQpzaHJ1YkZyYWNfbG5kX21lYW5fZW5zIDwtIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAic2hydWJGcmFjX2xuZF9tZWFuIikKYmFyZXNvaWxGcmFjX2xuZF9tZWFuX2VucyA8LSBtYWtlVGltZXNlcmllc0Vuc2VtYmxlKHZhcmlhYmxlID0gImJhcmVzb2lsRnJhY19sbmRfbWVhbiIpCiNjM1BmdEZyYWNfbG5kX21lYW5fZW5zIDwtIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAiYzNQZnRGcmFjX2xuZF9tZWFuX2VucyIpCiNjNFBmdEZyYWNfbG5kX21lYW5fZW5zIDwtIG1ha2VUaW1lc2VyaWVzRW5zZW1ibGUodmFyaWFibGUgPSAiYzRQZnRGcmFjX2xuZF9tZWFuX2VucyIpCgoKYGBgCgoKYGBge3IgcGxvdC1jYXJib24tY3ljbGUtdGltZXNlcmllcy1wcmltYXJ5LCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDEyfQoKcGFyKG1mcm93PSBjKDMsNCksIGxhcyA9IDEpCgpwbG90Y29sIDwtIGMobWFrZVRyYW5zcGFyZW50KCdibGFjaycsIDcwKSkKCnlsaW0gPSByYW5nZShjKG5wcF9lbnNbLDFdLCBucHBfZW5zWywxNjRdKSkKbWF0cGxvdCh5ZWFycywgdChucHBfZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnTlBQJywgeGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZShjKGNTb2lsX2Vuc1ssMV0sIGNTb2lsX2Vuc1ssMTY0XSkpCm1hdHBsb3QoeWVhcnMsIHQoY1NvaWxfZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnU29pbCBDYXJib24nLHhsYWIgPSAnJywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gcmFuZ2UoYyhjVmVnX2Vuc1ssMV0sIGNWZWdfZW5zWywxNjRdKSkKbWF0cGxvdCh5ZWFycywgdChjVmVnX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ1ZlZ2V0YXRpb24gQ2FyYm9uJyx4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKHRvdGFsX2xhbmRfY2FyYm9uX2VucykKbWF0cGxvdCh5ZWFycywgdCh0b3RhbF9sYW5kX2NhcmJvbl9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLCAKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnVG90YWwgTGFuZCBDYXJib24nLHhsYWIgPSAnJywKICAgICAgICBidHkgPSAnbicpCgoKeWxpbSA9IHJhbmdlKGxhaV9sbmRfbWVhbl9lbnMpCm1hdHBsb3QoeWVhcnMsIHQobGFpX2xuZF9tZWFuX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdMQUknLCBtYWluID0gJ0xlYWYgYXJlYSBpbmRleCcseGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZSh0cmVlRnJhY19sbmRfbWVhbl9lbnMpCm1hdHBsb3QoeWVhcnMsIHQodHJlZUZyYWNfbG5kX21lYW5fZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ2ZyYWN0aW9uJywgbWFpbiA9ICdUcmVlIGZyYWN0aW9uJyx4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKHNocnViRnJhY19sbmRfbWVhbl9lbnMpCm1hdHBsb3QoeWVhcnMsIHQoc2hydWJGcmFjX2xuZF9tZWFuX2VucyApLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnZnJhY3Rpb24nLCBtYWluID0gJ1NocnViIGZyYWN0aW9uJyx4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGJhcmVzb2lsRnJhY19sbmRfbWVhbl9lbnMpCm1hdHBsb3QoeWVhcnMsIHQoYmFyZXNvaWxGcmFjX2xuZF9tZWFuX2VucyApLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnZnJhY3Rpb24nLCBtYWluID0gJ2JhcmUgc29pbCBmcmFjdGlvbicseGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSBjKC0xMCwgMTApCm1hdHBsb3QoeWVhcnMsIHQobmJwX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsIAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdOQlAnLCB4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQogIAp5bGltID0gcmFuZ2UocmhfbG5kX3N1bV9lbnMpCm1hdHBsb3QoeWVhcnMsIHQocmhfbG5kX3N1bV9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDL3llYXInLCBtYWluID0gJ0hldGVyb3Ryb3BoaWMgUmVzcGlyYXRpb24nLCB4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGZMdWNfbG5kX3N1bV9lbnMpCm1hdHBsb3QoeWVhcnMsIHQoZkx1Y19sbmRfc3VtX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMveWVhcicsIG1haW4gPSAnTGFuZCB1c2UgY2hhbmdlIGVtaXNzaW9ucycsIHhsYWIgPSAnJywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gcmFuZ2UoZkhhcnZlc3RfbG5kX3N1bV9lbnMpCm1hdHBsb3QoeWVhcnMsIHQoZkhhcnZlc3RfbG5kX3N1bV9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDL3llYXInLCBtYWluID0gJ0hhcnZlc3QgQyBmbHV4IHRvIGF0bW9zcGhlcmUnLCB4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKCgoKYGBgCgoKYGBge3IgcGxvdC1jYXJib24tY3ljbGUtYW5vbWFseS10aW1lc2VyaWVzLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gNn0KCm5wcF9lbnNfYW5vbSA8LSBhbm9tYWxpemVUU21hdHJpeChucHBfZW5zLCAxOjIwKQpuYnBfZW5zX2Fub20gPC0gYW5vbWFsaXplVFNtYXRyaXgobmJwX2VucywgMToyMCkKY1NvaWxfZW5zX2Fub20gPC0gYW5vbWFsaXplVFNtYXRyaXgoY1NvaWxfZW5zLCAxOjIwKQpjVmVnX2Vuc19hbm9tIDwtIGFub21hbGl6ZVRTbWF0cml4KGNWZWdfZW5zLCAxOjIwKQp0b3RhbF9sYW5kX2NhcmJvbl9hbm9tIDwtIGFub21hbGl6ZVRTbWF0cml4KHRvdGFsX2xhbmRfY2FyYm9uX2VucywgMToyMCkKCnBhcihtZnJvdz0gYygxLDQpLCBsYXMgPSAxKQoKIyB5bGltID0gcmFuZ2UoLTEwLCAxMCkKI21hdHBsb3QoeWVhcnMsIHQobmJwX2Vuc19hbm9tKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKIyAgICAgICAgeWxhYiA9ICdOQlAgc3VtIEFub21hbHknLCBtYWluID0gJ05CUCBBbm9tYWx5JywKIyAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGMobnBwX2Vuc19hbm9tWywxXSwgbnBwX2Vuc19hbm9tWywxNjRdKSkKbWF0cGxvdCh5ZWFycywgdChucHBfZW5zX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnTlBQIHN1bSBBbm9tYWx5JywgbWFpbiA9ICdOUFAgQW5vbWFseScsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGMoY1NvaWxfZW5zX2Fub21bLDFdLCBjU29pbF9lbnNfYW5vbVssMTY0XSkpCm1hdHBsb3QoeWVhcnMsIHQoY1NvaWxfZW5zX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdTb2lsIENhcmJvbiBBbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gcmFuZ2UoYyhjVmVnX2Vuc19hbm9tWywxXSwgY1ZlZ19lbnNfYW5vbVssMTY0XSkpCm1hdHBsb3QoeWVhcnMsIHQoY1ZlZ19lbnNfYW5vbSksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ1ZlZ2V0YXRpb24gQ2FyYm9uIEFub21hbHknLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZSh0b3RhbF9sYW5kX2NhcmJvbl9hbm9tKQptYXRwbG90KHllYXJzLCB0KHRvdGFsX2xhbmRfY2FyYm9uX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdUb3RhbCBMYW5kIENhcmJvbiBBbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCgoKYGBgCgojIyBDYW4gd2UgdW5kZXJzdGFuZCBjaGFuZ2UgYW5kIGFic29sdXRlPwpgYGB7cn0KCgoKCgpgYGAKCgoKIyMgRnVuY3Rpb24gdG8gZXh0cmFjdCB0aGUgIm1vZGVybiB2YWx1ZSIgZGlyZWN0IGZyb20gdGhlIGZpbGUgKGxhc3QgMjAgeWVhcnMgb2YgdGhlIHRpbWVzZXJpZXMpCmBgYHtyIGV4dHJhY3QtbW9kZXJuLXZhbHVlLWZ1bmN0aW9uLCByZXN1bHRzID0gJ2hpZGUnfQojIGZvciBlYWNoIG9mIHRoZSB2YXJpYWJsZXMgaW4gdGhlIGZpbGUsIGF2ZXJhZ2UgdGhlIGxhc3QgMjAgeWVhcnMgYXMgdGhlICJtb2Rlcm4iIHZhbHVlLAojIGFuZCB0aGVuIHBsYWNlIGluIGEgbWF0cml4Cgptb2Rlcm5WYWx1ZSA8LSBmdW5jdGlvbihuYywgdmFyaWFibGUsIGl4KXsKICAjIEEgYmFzaWMgZnVuY3Rpb24gdG8gcmVhZCBhIHZhcmlhYmxlIGFuZCAKICAjIHRha2UgdGhlIG1lYW4gb2YgdGhlIHRpbWVzZXJpZXMgYXQgbG9jYXRpb25zIGl4CiAgZGF0IDwtIG5jdmFyX2dldChuYywgdmFyaWFibGUpCiAgb3V0IDwtIG1lYW4oZGF0W2l4XSkKICBvdXQKfQojMTQ0OjE2NCBpcyB0aGUgMTk5MzoyMDEzCm1vZGVyblZhbHVlKG5jID0gbmMsIHZhcmlhYmxlID0gIm5wcF9ubGltX2xuZF9tZWFuIiwgaXggPSAxNDQ6MTY0KQoKIyBhcHBseSB0byB0aGUgdGVzdCBmaWxlIHRvIGNoZWNrIGl0IHdvcmtzCnZlYyA8LSBzYXBwbHkodmFybGlzdCwgRlVOID0gbW9kZXJuVmFsdWUsIG5jID0gbmMsIGl4ID0gMTQ0OjE2NCkKCmBgYAoKIyMgTG9vcCB0byBleHRyYWN0IHRoZSAibW9kZXJuIHZhbHVlIiBvZiBhIG51bWJlciBvZiBtb2RlbCBvdXRwdXRzCgpgYGB7ciBsb2FkLWVuc2VtYmxlLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgcmVzdWx0cyA9IEZBTFNFfQojIEdlbmVyYXRlIGVuc2VtYmxlIG51bWJlcnMsIG1lYW4gb2YgdGhlIGxhc3QgMjAgeWVhcnMgb2YgdGhlIHRpbWVzZXJpZXMgKDE5OTQtMjAxMykKCmlmIChmaWxlLmV4aXN0cygiZW5zZW1ibGUucmRhdGEiKSkgewogIGxvYWQoImVuc2VtYmxlLnJkYXRhIikKfSBlbHNlIHsKICAKICBuZW5zID0gNDk5CiAgZGF0bWF0IDwtIG1hdHJpeChucm93ID0gbmVucywgbmNvbCA9IGxlbmd0aCh2YXJsaXN0KSkKICBjb2xuYW1lcyhkYXRtYXQpIDwtIHZhcmxpc3QKICAKICBlbnNsaXN0IDwtIHBhc3RlKCJQIiwgZm9ybWF0QygwOihuZW5zLTEpLCB3aWR0aD00LCBmbGFnPSIwIiksIHNlcD0iIikKICBmbG9jIDwtIHBhc3RlMChlbnNsb2MsZW5zbWVtYmVyLHN1YmRpcikKICAKICBmb3IoaSBpbiAxOm5lbnMpewogICAgCiAgICB2ZWMgPC0gcmVwKE5BLCBsZW5ndGgodmFybGlzdCkpCiAgICAKICAgIGVuc21lbWJlciA8LSBlbnNsaXN0W2ldIAogICAgCiAgICBmbiA8LSBwYXN0ZTAoZW5zbG9jLGVuc21lbWJlciwnL3N0YXRzLycsJ0pVTEVTLUVTLTFwMF8nLGVuc21lbWJlciwnX0FubnVhbF9nbG9iYWwubmMnKQogICAgI3ByaW50KGZuKQogICAgCiAgICB0cnkobmMgPC0gbmNfb3BlbihwYXN0ZTAoZm4pKSkKICAgIHRyeSh2ZWMgPC0gc2FwcGx5KHZhcmxpc3QsIEZVTiA9IG1vZGVyblZhbHVlLCBuYyA9IG5jLCBpeCA9IDE0NDoxNjQpKQogICAgZGF0bWF0W2ksIF0gPC0gdmVjCiAgICBuY19jbG9zZShuYykKICB9CiAgCiAgc2F2ZShuZW5zLCBkYXRtYXQsZW5zbGlzdCxmbG9jLCBmaWxlID0iZW5zZW1ibGUucmRhdGEiKQp9CmBgYAoKCiMjIENhbGN1bGF0ZSBhbiBlbnNlbWJsZSBvZiBhbm9tYWxpZXMgZm9yIGFsbCB2YXJpYWJsZXMKRm9yIGVhY2ggZW5zZW1ibGUgbWVtYmVyIGFuZCBlYWNoIHZhcmlhYmxlLCBjYWxjdWxhdGUgdGhlIGNoYW5nZSBmcm9tIHRoZSAyMCB5ZWFycyBhdCB0aGUgc3RhcnQgb2YgdGhlIHJ1biwgdG8gdGhlIHR3ZW50eSB5ZWFycyBhdCB0aGUgZW5kIG9mIHRoZSBydW4uCgpgYGB7cn0KdHNBbm9tYWx5IDwtIGZ1bmN0aW9uKG5jLCB2YXJpYWJsZSwgc3RhcnRpeCA9IDE6MjAsIGVuZGl4ID0gMTQ0OjE2NCl7CgogICMgQSBiYXNpYyBmdW5jdGlvbiB0byByZWFkIGEgdmFyaWFibGUgYW5kIGNhbGN1bGF0ZSB0aGUgYW5vbWFseSBhdCB0aGUgZW5kIG9mIHRoZSBydW4KICBkYXQgPC0gbmN2YXJfZ2V0KG5jLCB2YXJpYWJsZSkKICBlbmRNZWFuIDwtIG1lYW4oZGF0W2VuZGl4XSkKICBzdGFydE1lYW4gPC0gbWVhbihkYXRbc3RhcnRpeF0pCiAgb3V0IDwtIGVuZE1lYW4gLSBzdGFydE1lYW4KICBvdXQKfQoKdHNBbm9tYWx5KG5jID0gbmMsIHZhcmlhYmxlID0gIm5wcF9ubGltX2xuZF9tZWFuIikKYGBgCgpgYGB7ciBsb2FkLWFub21hbHktZW5zZW1ibGUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCByZXN1bHRzID0gRkFMU0V9CiMgR2VuZXJhdGUgZW5zZW1ibGUgIG1lYW4gb2YgdGhlIGxhc3QgMjAgeWVhcnMgb2YgdGhlIHRpbWVzZXJpZXMgKDE5OTQtMjAxMykKCmlmIChmaWxlLmV4aXN0cygiYW5vbWFseV9lbnNlbWJsZS5yZGF0YSIpKSB7CiAgbG9hZCgiYW5vbWFseV9lbnNlbWJsZS5yZGF0YSIpCn0gZWxzZSB7CiAgCiAgbmVucyA9IDQ5OQogIGRhdG1hdEFub20gPC0gbWF0cml4KG5yb3cgPSBuZW5zLCBuY29sID0gbGVuZ3RoKHZhcmxpc3QpKQogIGNvbG5hbWVzKGRhdG1hdEFub20pIDwtIHZhcmxpc3QKICAKICBlbnNsaXN0IDwtIHBhc3RlKCJQIiwgZm9ybWF0QygwOihuZW5zLTEpLCB3aWR0aD00LCBmbGFnPSIwIiksIHNlcD0iIikKICBmbG9jIDwtIHBhc3RlMChlbnNsb2MsZW5zbWVtYmVyLHN1YmRpcikKICAKICBmb3IoaSBpbiAxOm5lbnMpewogICAgCiAgICB2ZWMgPC0gcmVwKE5BLCBsZW5ndGgodmFybGlzdCkpCiAgICAKICAgIGVuc21lbWJlciA8LSBlbnNsaXN0W2ldIAogICAgCiAgICBmbiA8LSBwYXN0ZTAoZW5zbG9jLGVuc21lbWJlciwnL3N0YXRzLycsJ0pVTEVTLUVTLTFwMF8nLGVuc21lbWJlciwnX0FubnVhbF9nbG9iYWwubmMnKQogICAgI3ByaW50KGZuKQogICAgCiAgICB0cnkobmMgPC0gbmNfb3BlbihwYXN0ZTAoZm4pKSkKICAgIHRyeSh2ZWMgPC0gc2FwcGx5KHZhcmxpc3QsIEZVTiA9IHRzQW5vbWFseSwgbmMgPSBuYykpCiAgICBkYXRtYXRBbm9tW2ksIF0gPC0gdmVjCiAgICBuY19jbG9zZShuYykKICB9CiAgCiAgc2F2ZShuZW5zLCBkYXRtYXRBbm9tLCBlbnNsaXN0LGZsb2MsIGZpbGUgPSJhbm9tYWx5X2Vuc2VtYmxlLnJkYXRhIikKfQpgYGAKCgojIyBDbGVhbiBkYXRhIHNldHMgdG8gImxldmVsIDAiCkluaXRpYWwgY2xlYW4gb2YgZGF0YSBzZXQsIHJlbW92aW5nIHZhcmlhYmxlcyB0aGF0IGRvbid0IGNoYW5nZSwgYW5kIHJlbW92aW5nIE5BcyAobW9kZWxzIHRoYXQgZGlkbid0IHJ1bikuCmBgYHtyIGxldmVsLTAtb3V0cHV0fQoKWV9ubGV2ZWwwX2l4IDwtIHdoaWNoKGlzLm5hKGRhdG1hdFssJ3llYXInXSkpCgpZQW5vbV9ubGV2ZWwwX2l4IDwtIHdoaWNoKGlzLm5hKGRhdG1hdEFub21bLCd5ZWFyJ10pKQoKIyBUaGlzIHNob3VsZCBiZSB0cnVlIHRvIHByb2NlZWQsIG9yIHdlJ2xsIGhhdmUgdG8gc3RhcnQgZXhjbHVkaW5nIHRoZSBjb21iaW5lZCBzZXQuCmlkZW50aWNhbChZX25sZXZlbDBfaXgsIFlBbm9tX25sZXZlbDBfaXgpCgojIFkgaXMgdGhlIHdob2xlIGRhdGEgc2V0ClkgPC0gZGF0bWF0CiMgWV9sZXZlbDAgaXMgdGhlICdjbGVhbmVkJyBkYXRhIHNldCwgdHJ1bmNhdGVkIHRvIHZhcmlhYmxlcyB0aGF0IGNoYW5nZSwgYW5kIHJlbW92aW5nIE5BcwpZX2xldmVsMCA8LSBkYXRtYXRbLVlfbmxldmVsMF9peCwgLWMoMiwzMCwzMSldCllfbmxldmVsMCA8LSBkYXRtYXRbWV9ubGV2ZWwwX2l4LCAtYygyLCAzMCwgMzEpXQoKCiMgWSBpcyB0aGUgd2hvbGUgZGF0YSBzZXQKWUFub20gPC0gZGF0bWF0QW5vbQojIFkubGV2ZWwwIGlzIHRoZSAnY2xlYW5lZCcgZGF0YSBzZXQsIHRydW5jYXRlZCB0byB2YXJpYWJsZXMgdGhhdCBjaGFuZ2UsIGFuZCByZW1vdmluZyBOQXMKWUFub21fbGV2ZWwwIDwtIGRhdG1hdEFub21bLVlBbm9tX25sZXZlbDBfaXgsIC1jKDIsMzAsMzEpXQpZQW5vbV9ubGV2ZWwwIDwtIGRhdG1hdEFub21bWUFub21fbmxldmVsMF9peCwgLWMoMiwzMCwzMSldCgpgYGAKCmBgYHtyIGxldmVsLTAtaW5wdXR9CiMgbG9hZCB0aGUgb3JpZ2luYWwgZGVzaWduIGFuZCBpbnB1dCBzcGFjZSwgbm9ybWFsaXplIHRvIFswLTFdCgojIExvYWQgdXAgdGhlIGRhdGEKbGhzX2kgPSByZWFkLnRhYmxlKCd+L2JyYXppbENTU1AvY29kZS9icmF6aWxfY3NzcC9hbmFseXplX3UtYW83MzIvZGF0YS9FU19QUEVfaS9saHNfdS1hbzczMi50eHQnLCBoZWFkZXIgPSBUUlVFKQpsaHNfaWkgPSByZWFkLnRhYmxlKCd+L2JyYXppbENTU1AvY29kZS9icmF6aWxfY3NzcC9hbmFseXplX3UtYW83MzIvZGF0YS9FU19QUEVfaWkvbGhzX3UtYW83MzJhLnR4dCcsIGhlYWRlciA9IFRSVUUpCgp0b3BsZXZlbF9peCA9IDE6NDk5CgojIFRoZSByYXcgaW5wdXQgZGF0YSBpcyBhIGxhdGluIGh5cGVyY3ViZQpsaHMgPSByYmluZChsaHNfaSwgbGhzX2lpKVt0b3BsZXZlbF9peCwgXQpsaHNfbGV2ZWwwIDwtIGxoc1stWV9ubGV2ZWwwX2l4LF0KClggPSBub3JtYWxpemUobGhzKQpjb2xuYW1lcyhYKSA9IGNvbG5hbWVzKGxocykKClhfbGV2ZWwwIDwtIFhbLVlfbmxldmVsMF9peCxdClhfbmxldmVsMCA8LSBYW1lfbmxldmVsMF9peCxdCgpkID0gbmNvbChYKQojIGxvd2VyIGFuZCBoaWdoZXIgYm91bmQgb24gdGhlIG5vcm1hbGlzZWQgbWF0cml4IGZvciB2aXN1YWxpc2F0aW9uCnJ4ID0gcmJpbmQocmVwKDAsMzIpLCByZXAoMSwzMikpCmBgYAoKCiMjIFdoZXJlIGRpZCB0aGUgbW9kZWwgZmFpbCB0byBydW4/CigicHJvYmFiaWxpdHkgb2YgcnVuIGZhaWx1cmUiIENvdWxkIGJlIGFuIGludGVyZXN0aW5nIHByb2plY3QgLSBsb2dpdCB0cmFuc2Zvcm1hdGlvbiBmb3IgcHJvYmFiaWxpdHkgb2YgcnVuIGZhaWx1cmU/IFNvbWUgb3RoZXIgTUwgbGlrZSBTVk0/CgpUaGVyZSBhcmUgY2xlYXIgcnVuIGZhaWx1cmUgdGhyZXNob2xkcyBpbiB0aGUgcGFyYW1ldGVycyByb290ZF9mdF9pbyBhbmQgbGFpX21heCwgYW5kIHF1aXRlIHN0cm9uZyB2aXN1YWwgaW5kaWNhdGlvbnMgdGhhdCBhX3dsX2lvIGFuZCBiaW9faHVtX2NuIG1hdHRlci4KCgpORVhULCBoaXN0b2dyYW1zIG9mIGZhaWx1cmUgd2l0aCB0aGUgTEhTIHZhbHVlCmBgYHtyIHJ1bi1mYWlsdXJlLXBhaXJzLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDEyfQoKIyBOQiwgcGxvdHRpbmcgdGhlIGludmVyc2Ugb2YgdGhpcyBkb2Vzbid0IGdpdmUgeW91IG11Y2ggaW5mb3JtYXRpb24KCiNzaW1wbGUgd2F5CnBhcihvbWEgPSBjKDEwLDEwLDAsMCkpCiNwYXIoeHBkID0gVFJVRSkKcGFpcnMoWF9ubGV2ZWwwLCAKICAgICAgeGxpbSA9IGMoMCwxKSwgeWxpbSA9IGMoMCwxKSwKICAgICAgbGFiZWxzID0gMTpkLAogICAgICBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ3JlZCcsIDE1MCksCiAgICAgIGdhcCA9IDAsCiAgICAgIHBjaCA9IDIwLAogICAgICB4YXh0ID0nbicsIHlheHQgPSAnbicsCiAgICAgIGxvd2VyLnBhbmVsID0gTlVMTCkKCnJlc2V0KCkKCmxlZ2VuZCgnbGVmdCcsIGxlZ2VuZCA9IHBhc3RlKDE6ZCwgY29sbmFtZXMobGhzKSksIGNleCA9IDEuMiwgYnR5ID0gJ24nKQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOH0KCnBhcihtZnJvdyA9IGMoNCwgOCksIG1hciA9IGMoNCwzLDIsMSkpCgpmb3IoaSBpbiAxOmQpewogIAogIGhpc3QoWF9ubGV2ZWwwWyxpXSwgeGxpbSA9IGMoMCwxKSwgYnJlYWtzID0gc2VxKGZyb209MCwgdG8gPSAxLCBieSA9IDAuMSksIGNvbCA9ICdncmV5JywgbWFpbiA9ICcnLCB5bGltID0gYygwLDkpLAogICAgICAgYm9yZGVyID0gJ3doaXRlJywgeGxhYiA9IGNvbG5hbWVzKFhfbmxldmVsMClbaV0sIHlsYWIgPSAnJywgbGFzID0gMSwgY2V4LmxhYiA9IDEuNSkKfQoKYGBgCgoKIyMgVGVzdGluZyBHYXVzc2lhbiBQcm9jZXNzIGVtdWxhdG9ycwoKCiMjIyBOUFAgYXMgYSB0ZXN0CkZpcnN0LCB1c2UgbWVhbiBOUFAgYXMgYW4gZXhhbXBsZS4gSG93IGRvZXMgTlBQIHJlc3BvbmQgdG8gZWFjaCBwYXJhbWV0ZXI/IE5BcyBhcmUgcmVtb3ZlZCwgYnV0IHplcm8gdmFsdWVzIGFyZSBzdGlsbCBpbmNsdWRlZC4KCmBgYHtyIHBsb3QtbnBwLW1vZGVybiwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KcCA8LSBuY29sKFhfbGV2ZWwwKQoKeV9sZXZlbDAgPC0gWV9sZXZlbDBbLCducHBfbmxpbV9sbmRfc3VtJ10KCnBhcihtZnJvdyA9IGMoNSw3KSwgbWFyID0gYygzLDEsMywxKSwgb21hID0gYygxLDEsNSwxKSkKZm9yKGkgaW4gMTpwKXsKICBwbG90KFhfbGV2ZWwwWyxpXSwgeV9sZXZlbDAsIHhsYWIgPSAnJywgeWxhYiA9ICcnLCBtYWluID0gY29sbmFtZXMoWF9sZXZlbDApW2ldKQp9Cm10ZXh0KCdOUFAnLCBvdXRlciA9IFRSVUUsIHNpZGUgPSAzLCBjZXggPSAyLCBsaW5lID0gMikKCmBgYAoKCmBgYHtyIHBsb3QtbnBwLWNoYW5nZSwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KCnlhbm9tX2xldmVsMCA8LSBZQW5vbV9sZXZlbDBbLCducHBfbmxpbV9sbmRfc3VtJ10KCnBhcihtZnJvdyA9IGMoNSw3KSwgbWFyID0gYygzLDEsMywxKSwgb21hID0gYygxLDEsNSwxKSkKZm9yKGkgaW4gMTpwKXsKICBwbG90KFhfbGV2ZWwwWyxpXSwgeWFub21fbGV2ZWwwLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IGNvbG5hbWVzKFhfbGV2ZWwwKVtpXSkKfQptdGV4dCgnTlBQIGNoYW5nZSBvdmVyIHRpbWUnLCBvdXRlciA9IFRSVUUsIHNpZGUgPSAzLCBjZXggPSAyLCBsaW5lID0gMikKCmBgYAoKCiMjIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1vZGVybiBOUFAgYW5kIGNoYW5nZSBzaW5jZSAxODUwLgoKU29tZSBvdXRwdXRzIChlLmcgZkx1YywgZkhhcnZlc3QpIGhhdmUgYW4gYWxtb3N0IHBlcmZlY3QgMToxIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1vZGVybiB2YWx1ZSBhbmQgY2hhbmdlLCBzb21lICAobmJwLCBucHAsIHRyZWVGcmFjKSBxdWl0ZSBvciBtb2RlcmF0ZWx5IHN0cm9uZywgYW5kIHNvbWUgKGNzb2lsLCBjdmVnKSB2ZXJ5IHdlYWsgb3Igbm9uLWV4aXN0YW50LgpgYGB7ciBucHAtbW9kZXJuLXZzLWNoYW5nZSwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA4fQoKcGFyKG1mcm93ID0gYyg0LDcpLCBtYXIgPSBjKDMsMSwzLDEpLCBvbWEgPSBjKDQsNSwxLDEpKQoKcGRhc2ggPC0gbmNvbChZX2xldmVsMCkKCmZvcihpIGluIDE6cGRhc2gpewogIAogIHlfbGV2ZWwwIDwtIFlfbGV2ZWwwWyxpXQogIHlhbm9tX2xldmVsMCA8LSBZQW5vbV9sZXZlbDBbLGldCiAgCiAgcGxvdCh5X2xldmVsMCwgeWFub21fbGV2ZWwwLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IGNvbG5hbWVzKFlfbGV2ZWwwKVtpXSkKfQoKbXRleHQodGV4dCA9ICdNb2Rlcm4gdmFsdWUnLCBzaWRlID0gMSwgbGluZSA9IDIsIG91dGVyID0gVFJVRSwgY2V4ID0gMikKbXRleHQodGV4dCA9ICdDaGFuZ2UnLCBzaWRlID0gMiwgbGluZSA9IDIsIG91dGVyID0gVFJVRSwgY2V4ID0gMikKCmBgYAoKCgojIyBBIGNsZWFyIHRocmVzaG9sZCBpbiB0aGUgRjAgcGFyYW1ldGVyIGZvciBOUFAKSXQgYXBwZWFycyB0aGF0IHRoaXMgZW5zZW1ibGUgaXMgbGVzcyAiY2xlYXIgY3V0IiBpbiBoYXZpbmcgYW4gb3V0cHV0IHRoYXQgY2xlYXJseSBkaXN0aW5ndWlzaGVzIGJldHdlZW4gImZhaWxlZCIgKG9yIGNsb3NlIHRvIGl0KSwgYW5kICJub3QgZmFpbGVkIi4KCkhhdmluZyBzYWlkIHRoYXQsIGhhdmluZyBhbiBGMCBvdmVyIGEgdGhyZXNob2xkIHNlZW1zIHRvIGtpbGwgdGhlIGNhcmJvbiBjeWNsZSwgYXMgYmVmb3JlLiBIZXJlLCB3ZSd2ZSBzZXQgYSB0aHJlc2hvbGQgb2YgMC45IChvbiB0aGUgbm9ybWFsaXNlZCBzY2FsZSkgZm9yIEYwLCBhbmQgd2UgcmVtb3ZlIG1lbWJlcnMgb2YgdGhlIGVuc2VtYmxlIHdpdGggYSBsYXJnZXIgRjAgdGhhbiB0aGF0IHdoZW4gd2UgYnVpbGQgZW11bGF0b3JzLgoKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA4fQoKcGFyKG1mcm93ID0gYygyLDEpKQpwbG90KGxocyRmMF9pbywgZGF0bWF0WywgJ25wcF9ubGltX2xuZF9zdW0nXSwgbWFpbiA9ICdNdWx0aXBsaWNhdGlvbiBmYWN0b3InLCB4bGFiID0gJ2YwX2lvJywgeWxhYiA9ICdOUFAgc3VtJykKcGxvdChYX2xldmVsMFssJ2YwX2lvJ10sIFlfbGV2ZWwwWywgJ25wcF9ubGltX2xuZF9zdW0nXSwgeGxhYiA9ICdmMF9pbycsIG1haW4gPSAnTm9ybWFsaXplZCcsIHlsYWIgPSAnTlBQIHN1bScpCmFibGluZSh2ID0gMC45KQoKYGBgCgoKIyMgTGV2ZWwgMSBjb25zdHJhaW50IC0gcmVtb3ZlIGVuc2VtYmxlIG1lbWJlcnMgd2l0aCBGMCBhYm92ZSB0aHJlc2hvbGQKVGhlIGxldmVsIDEgY29uc3RyYWludCByZW1vdmVzIGFueSBpbnB1dCB3aXRoIEYwIGdyZWF0ZXIgdGhhbiAwLjkgKG5vcm1hbGlzZWQpLCB3aGljaCByZW1vdmVzIG1hbnkgb2YgdGhlIHplcm8tY2FyYm9uLWN5Y2xlIG1lbWJlcnMgdXAgZnJvbnQuIFRoZXJlIGFyZSA0MjQgZW5zbWJsZSBtZW1iZXJzIHJlbWFpbmluZy4KClRoaXMgZG9lcyBjb25zdHJhaW50IHNlcXVlbnRpYWxseSwgd2hpY2ggbWF5IG5vdCBiZSBhIGdvb2QgaWRlYS4gCmBgYHtyfQpsZXZlbDFfaXggPC0gd2hpY2goWF9sZXZlbDBbLCAnZjBfaW8nXSA8IDAuOSkKClhfbGV2ZWwxIDwtIFhfbGV2ZWwwW2xldmVsMV9peCwgXQpZX2xldmVsMSA8LSBZX2xldmVsMFtsZXZlbDFfaXgsIF0KCllBbm9tX2xldmVsMSA8LSBZQW5vbV9sZXZlbDBbbGV2ZWwxX2l4LCBdCgp5X2xldmVsMSA8LSBZX2xldmVsMVssICducHBfbmxpbV9sbmRfc3VtJ10KYGBgCgojIyMgQ29tcGFyaXNvbiBvZiBsZXZlbCAwIGFuZCBsZXZlbCAxIGVtdWxhdG9ycyBmb3IgTlBQIChtb2Rlcm4gdmFsdWUpCgpgYGB7ciwgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDcsIHJlc3VsdHMgPSAnaGlkZScsIHdhcm5pbmc9RkFMU0V9CmVtX25wcF9sZXZlbDAgPC0ga20ofi4sIGRlc2lnbiA9IFhfbGV2ZWwwLCAgcmVzcG9uc2UgPSB5X2xldmVsMCkKZW1fbnBwX2xldmVsMSA8LSBrbSh+LiwgZGVzaWduID0gWF9sZXZlbDEsICByZXNwb25zZSA9IHlfbGV2ZWwxKQoKZW1fbnBwX2xldmVsMF9tcyA8LSBrbSh+LiwgZGVzaWduID0gWF9sZXZlbDAsICByZXNwb25zZSA9IHlfbGV2ZWwwLCBtdWx0aXN0YXJ0ID0gNCkKZW1fbnBwX2xldmVsMV9tcyA8LSBrbSh+LiwgZGVzaWduID0gWF9sZXZlbDEsICByZXNwb25zZSA9IHlfbGV2ZWwxLCBtdWx0aXN0YXJ0ID0gNCkKCgpgYGAKCgogIyBQbG90IHRoZSByZWd1bGFyIGttIGVtdWxhdG9yLiBEb2Vzbid0IGxvb2sgZ3JlYXQuCgpgYGB7ciBwbG90LWVtLW5wcC1sZXZlbDAsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3fQpwbG90KGVtX25wcF9sZXZlbDApCmBgYAoKYGBge3IgcGxvdC1lbS1ucHAtbGV2ZWwxLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gN30KcGxvdChlbV9ucHBfbGV2ZWwxKQpgYGAKCgojIyMgTGVhdmUtb25lLW91dCBzdW1tYXJpZXMgb2YgTlBQIGVtdWxhdG9ycwpgYGB7cn0KCmxvb19ucHBfbGV2ZWwwIDwtIGxlYXZlT25lT3V0LmttKGVtX25wcF9sZXZlbDAsIHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSkKbG9vX25wcF9sZXZlbDEgPC0gbGVhdmVPbmVPdXQua20oZW1fbnBwX2xldmVsMSwgdHlwZSA9ICdVSycsIHRyZW5kLnJlZXN0aW0gPSBUUlVFKQoKUk1TRSAoIGxvb19ucHBfbGV2ZWwwJG1lYW4sIHlfbGV2ZWwwKQpSTVNFICggbG9vX25wcF9sZXZlbDEkbWVhbiwgeV9sZXZlbDEpCgoKIyBIb3cgYWJvdXQgTUFFIG92ZXIgdGhlIHJhbmdlCnByb3BfbWFlIDwtIGZ1bmN0aW9uKFksIFlwcmVkKXsKICAjIG1lYW4gYWJzb2x1dGUgZXJyb3IgYXMgYSBwcm9wb3J0aW9uIG9mIHRoZSByYW5nZSBvZiBvdXRwdXQKICAKICBhYnNkaWZmIDwtIGFicyhkaWZmKHJhbmdlKFkpKSkKICAKICBtYWUgPC0gTUFFKFksIFlwcmVkKQogIAogIHByb3BtYWUgPC0gKG1hZSAvIGFic2RpZmYpICogMTAwCiAgCiAgcHJvcG1hZQogIAp9Cgpwcm9wX21hZSh5X2xldmVsMCwgbG9vX25wcF9sZXZlbDAkbWVhbikKCnByb3BfbWFlKHlfbGV2ZWwxLCBsb29fbnBwX2xldmVsMSRtZWFuKQoKCgoKCgpgYGAKCgpgYGB7cn0KCgoKCmBgYAoKYGBge3J9CgojIE1PVkUgVEhJUyBUTyBJTVBUT09MUyBPUiBFTVRPT0xTCiMgR2l2ZW4gYSBrbSBtb2RlbCwgcHJvZHVjZSBzb21lIGVycm9yIHN0YXRpc3RpY3MKCgpgYGAKCmBgYHtyfQoKIyBJdCBkb2Vzbid0IGxvb2sgbGlrZSBNdWx0aXN0YXJ0IG1ha2VzIGEgYmlnIGRpZmZlcmVuY2UgYXQgYWxsIGZvciBOUFAKZXJyc3RhdHNfbnBwX2xldmVsMCA8LSBrbUxvb1N0YXRzKGttID0gZW1fbnBwX2xldmVsMCkKZXJyc3RhdHNfbnBwX2xldmVsMF9tcyA8LSBrbUxvb1N0YXRzKGttID0gZW1fbnBwX2xldmVsMF9tcykKCmVycnN0YXRzX25wcF9sZXZlbDEgPC0ga21Mb29TdGF0cyhrbSA9IGVtX25wcF9sZXZlbDEpCmVycnN0YXRzX25wcF9sZXZlbDFfbXMgPC0ga21Mb29TdGF0cyhrbSA9IGVtX25wcF9sZXZlbDFfbXMpCgoKIyBwcm9wb3J0aW9uYWwgbWVhbiBhYnNvbHV0ZSBlcnJvcgplcnJzdGF0c19ucHBfbGV2ZWwwJHBtYWUKZXJyc3RhdHNfbnBwX2xldmVsMF9tcyRwbWFlCgoKZXJyc3RhdHNfbnBwX2xldmVsMSRwbWFlCmVycnN0YXRzX25wcF9sZXZlbDFfbXMkcG1hZQoKCgoKYGBgCgoKCgoKYGBge3J9CiMgRGljZUV2YWwgaXMgdXNlZnVsIGJ1dCBzbG93L2F3a3dhcmQKCiMgREVfZW1fbnBwX2xldmVsMCA8LSBtb2RlbEZpdChYID0gWF9sZXZlbDAsIFkgPSB5X2xldmVsMCwgdHlwZSA9ICdLcmlnaW5nJywgZm9ybXVsYSA9IH4uICkKIyBERV9lbV9ucHBfbGV2ZWwxIDwtIG1vZGVsRml0KFggPSBYX2xldmVsMSwgWSA9IHlfbGV2ZWwxLCB0eXBlID0gJ0tyaWdpbmcnLCBmb3JtdWxhID0gfi4gKQoKIyBucHBfZW1fY3ZfbGV2ZWwwIDwtIGNyb3NzVmFsaWRhdGlvbihERV9lbV9ucHBfbGV2ZWwwLCA1KQojIG5wcF9lbV9jdl9sZXZlbDEgIDwtIGNyb3NzVmFsaWRhdGlvbihERV9lbV9ucHBfbGV2ZWwxLCA1KQoKYGBgCgoKCiMjIENvbnN0cmFpbiBmaXJzdCBhbmQgdGhlbiBkbyBzZW5zaXRpdml0eSBhbmFseXNpcz8KVGhlIHByb2JsZW0gd2l0aCBkb2luZyBjb25zdHJhaW50IGZpcnN0IGlzIHRoYXQgeW91IGVuZCB1cCB3aXRoIGEgbm9uLWh5cGVyY3ViZSBzaGFwZWQgaW5wdXQgc3BhY2UgKGNvcm5lcnMgaGF2ZSBiZWVuIGtub2NrZWQgb2ZmIGJ5IGNvbnN0cmFpbnQpLCB3aGljaCBpcyBub3QgaWRlYWwuIFdlIG1pZ2h0IHRoZXJlZm9yZSB3YW50IGRpZmZlcmVudCBzZW5zaXRpdml0eSBtZWFzdXJlcyBmb3IgcHJlLSBhbmQgcG9zdC1jb25zdHJhaW5lZCBlbnNlbWJsZS4KCgpgYGB7cn0KCiNzZW5zdmFyIG5lZWRzIHRvIGdvIGludG8gZW10b29scyB3aXRoIG9hYXRfZGVzaWduCnNlbnN2YXIgPC0gZnVuY3Rpb24ob2FhdF9wcmVkLCBuLCBkKXsKICAjIENhbGN1bGF0ZSB2YXJpYW5jZSBhcyBhIGdsb2JhbCBzZW5zaXRpdml0eSBtZWFuc3VyZQogIG91dCA9IHJlcChOQSxkKQogIGZvcihpIGluIDE6ZCl7CiAgICBpeCA9IHNlcShmcm9tID0gKChpKm4pIC0gKG4tMSkpLCB0byA9ICAoaSpuKSwgYnkgPSAxKQogICAgb3V0W2ldID0gdmFyKG9hYXRfcHJlZCRtZWFuW2l4XSkKICB9CiAgb3V0Cn0KCgpgYGAKCgpgYGB7cn0KdHdvU3RlcF9nbG1uZXQgPC0gZnVuY3Rpb24oWCwgeSwgbnVnZ2V0PU5VTEwsIG51Z2dldEVzdGltPUZBTFNFLCBub2lzZVZhcj1OVUxMLCBzZWVkPU5VTEwsIHRyYWNlPUZBTFNFLCBtYXhpdD0xMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUkVQT1JUPTEwLCBmYWN0cj0xZTcsIHBndG9sPTAuMCwgcGFyaW5pdD1OVUxMLCBwb3BzaXplPTEwMCl7CiAgIyBVc2UgbGFzc28gdG8gcmVkdWNlIGlucHV0IGRpbWVuc2lvbiBvZiBlbXVsYXRvciBiZWZvcmUKICAjIGJ1aWxkaW5nLgogIGNvbnRyb2xfbGlzdCA9IGxpc3QodHJhY2U9dHJhY2UsIG1heGl0PW1heGl0LCBSRVBPUlQ9UkVQT1JULCBmYWN0cj1mYWN0ciwgcGd0b2w9cGd0b2wsIHBvcC5zaXplPXBvcHNpemUpCiAgeHZhcnMgPSBjb2xuYW1lcyhYKQogIGRhdGEgPSBkYXRhLmZyYW1lKHJlc3BvbnNlPXksIHg9WCkKICBjb2xuYW1lcyhkYXRhKSA8LSBjKCJyZXNwb25zZSIsIHh2YXJzKQogIG52YWwgPSBsZW5ndGgoeSkKICAKICAjIGZpdCBhIGxhc3NvIGJ5IGNyb3NzIHZhbGlkYXRpb24KICBsaWJyYXJ5KGdsbW5ldCkKICBmaXRfZ2xtbmV0X2N2ID0gY3YuZ2xtbmV0KHg9WCx5PXkpCiAgCiAgIyBUaGUgbGFiZWxzIG9mIHRoZSByZXRhaW5lZCBjb2VmZmljaWVudHMgYXJlIGhlcmUKICAjIChyZXRhaW5zIGludGVyY2VwdCBhdCBpbmRleCB6ZXJvKQogIGNvZWZfaSA9IChjb2VmKGZpdF9nbG1uZXRfY3YsIHMgPSAibGFtYmRhLjFzZSIpKUBpCiAgbGFicyA9IGxhYmVscyhjb2VmKGZpdF9nbG1uZXRfY3YsIHMgPSAibGFtYmRhLjFzZSIpKVtbMV1dCiAgbGFicyA9IGxhYnNbLTFdICMgcmVtb3ZlIGludGVyY2VwdAogIGdsbW5ldF9yZXRhaW5lZCA9IGxhYnNbY29lZl9pXQogIAogIHN0YXJ0X2Zvcm0gPSBhcy5mb3JtdWxhKHBhc3RlKCJ+ICIsIHBhc3RlKGdsbW5ldF9yZXRhaW5lZCAsIGNvbGxhcHNlPSAiKyIpKSkKICBtID0ga20oc3RhcnRfZm9ybSwgZGVzaWduPVgsIHJlc3BvbnNlPXksIG51Z2dldD1udWdnZXQsIHBhcmluaXQ9cGFyaW5pdCwKICAgICAgICAgbnVnZ2V0LmVzdGltPW51Z2dldEVzdGltLCBub2lzZS52YXI9bm9pc2VWYXIsIGNvbnRyb2w9Y29udHJvbF9saXN0KQogIAogIHJldHVybihsaXN0KHg9WCwgeT15LCBudWdnZXQ9bnVnZ2V0LCBudWdnZXRFc3RpbT1udWdnZXRFc3RpbSwKICAgICAgICAgICAgICBub2lzZVZhcj1ub2lzZVZhciwgZW11bGF0b3I9bSwgc2VlZD1zZWVkLCBjb2Vmcz1tQGNvdmFyaWFuY2VAcmFuZ2UudmFsLAogICAgICAgICAgICAgIHRyZW5kcz1tQHRyZW5kLmNvZWYsIG1lYW5UZXJtcz1hbGwudmFycyhzdGFydF9mb3JtKSwgZml0X2dsbW5ldF9jdj1maXRfZ2xtbmV0X2N2KSkKfQpgYGAKCgpgYGB7cn0KCnR3b1N0ZXBfc2VucyA8LSBmdW5jdGlvbihYLCB5LCBuPTIxLCBwcmVkdHlwZSA9ICdVSycsIG51Z2dldD1OVUxMLCBudWdnZXRFc3RpbT1GQUxTRSwgbm9pc2VWYXI9TlVMTCwgc2VlZD1OVUxMLCB0cmFjZT1GQUxTRSwgbWF4aXQ9MTAwLAogICAgICAgICAgICAgICAgICAgICAgICBSRVBPUlQ9MTAsIGZhY3RyPTFlNywgcGd0b2w9MC4wLCBwYXJpbml0PU5VTEwsIHBvcHNpemU9MTAwKXsKICAjIFNlbnNpdGl2aXR5IGFuYWx5c2lzIHdpdGggdHdvU3RlcCBlbXVsYXRvci4gCiAgIyBDYWxjdWxhdGVzIHRoZSB2YXJpYW5jZSBvZiB0aGUgb3V0cHV0IHZhcmllZCBvbmUgYXQgYSB0aW1lIGFjcm9zcyBlYWNoIGlucHV0LgogIGQgPSBuY29sKFgpCiAgWF9ub3JtIDwtIG5vcm1hbGl6ZShYKQogIFhfb2FhdCA8LSBvYWF0X2Rlc2lnbihYX25vcm0sIG4sIG1lZCA9IFRSVUUpCiAgY29sbmFtZXMoWF9vYWF0KSA9IGNvbG5hbWVzKFgpCiAgCiAgdHdvU3RlcF9lbSA9IHR3b1N0ZXBfZ2xtbmV0KFg9WCwgeT15LCBudWdnZXQ9bnVnZ2V0LCBudWdnZXRFc3RpbT1udWdnZXRFc3RpbSwgbm9pc2VWYXI9bm9pc2VWYXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZCwgdHJhY2U9dHJhY2UsIG1heGl0PW1heGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRVBPUlQ9UkVQT1JULCBmYWN0cj1mYWN0ciwgcGd0b2w9cGd0b2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmluaXQ9cGFyaW5pdCwgcG9wc2l6ZT1wb3BzaXplKQogIAogIG9hYXRfcHJlZCA9IHByZWRpY3QodHdvU3RlcF9lbSRlbXVsYXRvciwgbmV3ZGF0YSA9IFhfb2FhdCwgdHlwZSA9IHByZWR0eXBlKQogIAogIHNlbnMgPSBzZW5zdmFyKG9hYXRfcHJlZCA9IG9hYXRfcHJlZCwgbj1uLCBkPWQpCiAgb3V0ID0gc2VucwogIG91dAp9CmBgYAoKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CgppZiAoZmlsZS5leGlzdHMoIm9hdF90d29zdGVwLnJkYXRhIikpIHsKICBsb2FkKCJvYXRfdHdvc3RlcC5yZGF0YSIpCn0gZWxzZSB7Cm9hdF90ZXN0IDwtIHR3b1N0ZXBfc2VucyhYID0gWF9sZXZlbDEsIHkgPSB5X2xldmVsMSkKCgpzYXZlKG9hdF90ZXN0LCBmaWxlID0gIm9hdF90d29zdGVwLnJkYXRhIikKfQoKYGBgCgoKYGBge3J9CnlfbmFtZXNfc3VtIDwtIGMoJ25icF9sbmRfc3VtJywgJ2ZMdWNfbG5kX3N1bScsICducHBfbmxpbV9sbmRfc3VtJywgJ2NTb2lsX2xuZF9zdW0nLAogICAgICAgICAgICAnY1ZlZ19sbmRfc3VtJywgJ2xhbmRDb3ZlckZyYWNfbG5kX3N1bScsICdmSGFydmVzdF9sbmRfc3VtJywKICAgICAgICAgICAgJ2xhaV9sbmRfc3VtJywgJ3JoX2xuZF9zdW0nLCAndHJlZUZyYWNfbG5kX3N1bScsICdjM1BmdEZyYWNfbG5kX3N1bScsIAogICAgICAgICAgICAnYzRQZnRGcmFjX2xuZF9zdW0nLCAnc2hydWJGcmFjX2xuZF9zdW0nLCAnYmFyZXNvaWxGcmFjX2xuZF9zdW0nKQoKCgoKaWYgKGZpbGUuZXhpc3RzKCJvYWF0X1kucmRhdGEiKSkgewogIGxvYWQoIm9hYXRfWS5yZGF0YSIpCn0gZWxzZSB7CiAgCiAgCm9hdF92YXJfc2Vuc21hdF9ZIDwtIG1hdHJpeChOQSwgbnJvdyA9IGxlbmd0aCh5X25hbWVzX3N1bSksIG5jb2wgPSBuY29sKFhfbGV2ZWwxKSkKCmZvcihpIGluIDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSl7CiAgCiAgeW5hbWUgPC0geV9uYW1lc19zdW1baV0KICB5IDwtIFlfbGV2ZWwxWywgeW5hbWVdCiAgb2F0IDwtIHR3b1N0ZXBfc2VucyhYID0gWF9sZXZlbDEsIHkgPSB5KQogIG9hdF92YXJfc2Vuc21hdF9ZW2ksIF0gPC0gb2F0Cn0KCnNhdmUoeV9uYW1lc19zdW0sIG9hdF92YXJfc2Vuc21hdF9ZLCBmaWxlID0gIm9hYXRfWS5yZGF0YSIpCn0KYGBgCgojIyBJbml0aWFsIHNlbnNpdGl2aXR5IE1hdHJpeApJdCBsb29rcyBhcyB0aG91Z2ggYndsX2lvIGlzIHZlcnkgaW5mbHVlbnRpYWwgYWNyb3NzIGEgbnVtYmVyIG9mIHZhcmlhYmxlcywgZXZlbiB0aG91Z2ggaXQgZGlkbid0IGFwcGVhciB0aGF0IGludGVyZXN0aW5nIGluIHRoZSBwYXJnaW5hbCBwbG90cy4gV2h5IGlzIHRoYXQ/CgpgYGB7ciwgZmlnLndpZHRoPSAxMCwgZmlnLmhlaWdodCA9IDZ9CiMgbm9ybWFsaXplIHRoZSBzZW5zaXRpdml0eSBtYXRyaXgKY29sbmFtZXMob2F0X3Zhcl9zZW5zbWF0X1kpIDwtIGNvbG5hbWVzKFhfbGV2ZWwxKQpyb3duYW1lcyhvYXRfdmFyX3NlbnNtYXRfWSkgPC0geV9uYW1lc19zdW0KCiN0ZXN0IDwtIG5vcm1hbGl6ZSh0KG9hdC52YXIuc2Vuc21hdCkpCgojaW1hZ2UodGVzdCkKI3BhcigpCmhlYXRtYXAob2F0X3Zhcl9zZW5zbWF0X1ksIFJvd3YgPSBOQSwgQ29sdiA9IE5BLCBtYXIgPSBjKDEwLDEwKSwgc2NhbGUgPSAncm93JykKaGVhdG1hcChvYXRfdmFyX3NlbnNtYXRfWSwgbWFyID0gYygxMCwxMCksIHNjYWxlID0gJ3JvdycpCgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0xMiwgZmlnLmhlaWdodCA9IDd9Cgpub3Jtc2Vuc19ZIDwtIG5vcm1hbGl6ZSh0KG9hdF92YXJfc2Vuc21hdF9ZKSkKCnBhcihtYXIgPSBjKDEyLDEyLDUsMikpCmltYWdlKG5vcm1zZW5zX1ksIGF4ZXMgPSBGQUxTRSwgY29sID0gYmx1ZXMpCmF4aXMoMSwgYXQgPSBzZXEoZnJvbSA9IDAsIHRvID0gMSwgbGVuZ3RoLm91dCA9IHApLCBsYWJlbHMgPSBjb2xuYW1lcyhYX2xldmVsMSksIGxhcyA9IDIpCmF4aXMoMiwgYXQgPSBzZXEoZnJvbSA9IDAsIHRvID0gMSwgbGVuZ3RoLm91dCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpLCBsYWJlbHMgPSB5X25hbWVzX3N1bSwgbGFzID0gMSkKbXRleHQoJ09uZS1hdC1hLXRpbWUgc2Vuc2l0aXZpdHksIHZhcmlhbmNlIGFjcm9zcyBsZXZlbCAxIGVuc2VtYmxlJywgc2lkZSA9IDMsIGFkaiA9IDAsIGxpbmUgPSAyLCBjZXggPSAxLjgpCgpgYGAKCgoKIyMgUmUtZXhhbWluZSBid2xfaW8KQSBjbG9zZXIgbG9vayBhdCBid2xfaW8gbm93IHRoYXQgdGhlIGltcGFjdCBvZiBmMF9pbyBoYXMgYmVlbiByZW1vdmVkIHNob3dzIGEgbGFyZ2UgbnVtYmVyIG9mICJ6ZXJvIiBOUFAgd2hlbiBid2xfaW8gaXMgYXQgbG93IHZhbHVlcywgd2hpY2ggY291bGQgd2VsbCBiZSB0aGUgc291cmNlIG9mIGFwcGFyZW50IHNlbnNpdGl2aXR5LgoKVGFrZSBvbmx5IGhpZ2hlciB2YWx1ZXMgb2YgYndsX2lvIGZvciB0aGUgbmV4dCByb3VuZCBvZiBjb25zdHJhaW50cy4KCmBgYHtyLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDEyfQoKcCA8LSBuY29sKFhfbGV2ZWwxKQoKeV9sZXZlbDEgPC0gWV9sZXZlbDFbLCducHBfbmxpbV9sbmRfc3VtJ10KCnBhcihtZnJvdyA9IGMoNSw3KSwgbWFyID0gYygzLDEsMywxKSkKZm9yKGkgaW4gMTpwKXsKICBwbG90KFhfbGV2ZWwxWyxpXSwgeV9sZXZlbDEsIHhsYWIgPSAnJywgeWxhYiA9ICcnLCBtYWluID0gY29sbmFtZXMoWF9sZXZlbDEpW2ldKQp9CgpgYGAKCiMgUmVtb3ZlIGVuc2VtYmxlIG1lbWJlcnMgd2l0aCBsb3cgYl93bCBhbmQgc2VlIGlmIHRoZSBzZW5zaXRpdml0eSBhbmFseXNlcyBjaGFuZ2UgYW5kIHRoZSBlbXVsYXRvcnMgZ2V0IGJldHRlci4KCmBgYHtyfQpsZXZlbDFhX2l4IDwtIHdoaWNoKFhfbGV2ZWwwWywgJ2YwX2lvJ10gPCAwLjkgJiBYX2xldmVsMFssICdiX3dsX2lvJ10gPiAwLjE1ICkKClhfbGV2ZWwxYSA8LSBYX2xldmVsMFtsZXZlbDFhX2l4LCBdCllfbGV2ZWwxYSA8LSBZX2xldmVsMFtsZXZlbDFhX2l4LF0KCllBbm9tX2xldmVsMWEgPC0gWUFub21fbGV2ZWwwW2xldmVsMWFfaXgsIF0KCnlfbGV2ZWwxYSA8LSBZX2xldmVsMWFbLCAnbnBwX25saW1fbG5kX3N1bSddCgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDcsIHJlc3VsdHMgPSAnaGlkZScsIHdhcm5pbmc9RkFMU0V9CmVtX2xldmVsMWEgPC0ga20ofi4sIGRlc2lnbiA9IFhfbGV2ZWwxYSwgIHJlc3BvbnNlID0geV9sZXZlbDFhKQpgYGAKCgogIyBQbG90IHRoZSByZWd1bGFyIGttIGVtdWxhdG9yLgoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3fQpwbG90KGVtX2xldmVsMWEpCgoKYGBgCgoKYGBge3J9CmlmIChmaWxlLmV4aXN0cygib2FhdF9sZXZlbDFhX1kucmRhdGEiKSkgewogIGxvYWQoIm9hYXRfbGV2ZWwxYV9ZLnJkYXRhIikKfSBlbHNlIHsKICAKICAKb2F0X3Zhcl9zZW5zbWF0X2xldmVsMWFfWSA8LSBtYXRyaXgoTkEsIG5yb3cgPSBsZW5ndGgoeV9uYW1lc19zdW0pLCBuY29sID0gbmNvbChYX2xldmVsMWEpKQoKZm9yKGkgaW4gMTpsZW5ndGgoeV9uYW1lc19zdW0pKXsKICAKICB5bmFtZSA8LSB5X25hbWVzX3N1bVtpXQogIHkgPC0gWV9sZXZlbDFhWywgeW5hbWVdCiAgb2F0IDwtIHR3b1N0ZXBfc2VucyhYID0gWF9sZXZlbDFhLCB5ID0geSkKICBvYXRfdmFyX3NlbnNtYXRfbGV2ZWwxYV9ZW2ksIF0gPC0gb2F0Cn0KCnNhdmUoeV9uYW1lc19zdW0sIG9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1ksIGZpbGUgPSAib2FhdF9sZXZlbDFhX1kucmRhdGEiKQp9CgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KCnAgPC0gbmNvbChYX2xldmVsMWEpCgp5X2xldmVsMWEgPC0gWV9sZXZlbDFhWywnbnBwX25saW1fbG5kX3N1bSddCgpwYXIobWZyb3cgPSBjKDUsNyksIG1hciA9IGMoMywxLDMsMSkpCmZvcihpIGluIDE6cCl7CiAgcGxvdChYX2xldmVsMWFbLGldLCB5X2xldmVsMWEsIHhsYWIgPSAnJywgeWxhYiA9ICcnLCBtYWluID0gY29sbmFtZXMoWF9sZXZlbDFhKVtpXSwgeGxpbSA9IGMoMCwxKSkKfQoKYGBgCgojIyBXaXRoIGJfd2wgdHJ1bmNhdGVkLCB3ZSBjYW4gY2xlYXJseSBzZWUgdGhlIHNlbnNpdGl2aXRpZXMgY2hhbmdlLgoKYGBge3IsIGZpZy53aWR0aD0gMTAsIGZpZy5oZWlnaHQgPSA2fQojIG5vcm1hbGl6ZSB0aGUgc2Vuc2l0aXZpdHkgbWF0cml4CmNvbG5hbWVzKG9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1kpIDwtIGNvbG5hbWVzKFhfbGV2ZWwxYSkKcm93bmFtZXMob2F0X3Zhcl9zZW5zbWF0X2xldmVsMWFfWSkgPC0geV9uYW1lc19zdW0KCiN0ZXN0IDwtIG5vcm1hbGl6ZSh0KG9hdC52YXIuc2Vuc21hdCkpCgojaW1hZ2UodGVzdCkKI3BhcigpCmhlYXRtYXAob2F0X3Zhcl9zZW5zbWF0X2xldmVsMWFfWSwgUm93diA9IE5BLCBDb2x2ID0gTkEsIG1hciA9IGMoMTAsMTApLCBzY2FsZSA9ICdyb3cnKQpoZWF0bWFwKG9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1ksIG1hciA9IGMoMTAsMTApLCBzY2FsZSA9ICdyb3cnKQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9MTIsIGZpZy5oZWlnaHQgPSA3fQoKbm9ybXNlbnNfbGV2ZWwxYV9ZIDwtIG5vcm1hbGl6ZSh0KG9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1kpKQoKcGFyKG1hciA9IGMoMTIsMTIsNSwyKSkKaW1hZ2Uobm9ybXNlbnNfbGV2ZWwxYV9ZLCBheGVzID0gRkFMU0UsIGNvbCA9IGJsdWVzKQpheGlzKDEsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBwKSwgbGFiZWxzID0gY29sbmFtZXMoWF9sZXZlbDFhKSwgbGFzID0gMikKYXhpcygyLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSksIGxhYmVscyA9IHlfbmFtZXNfc3VtLCBsYXMgPSAxKQptdGV4dCgnT25lLWF0LWEtdGltZSBzZW5zaXRpdml0eSwgdmFyaWFuY2UgYWNyb3NzIGxldmVsIDFhIGVuc2VtYmxlJywgc2lkZSA9IDMsIGFkaiA9IDAsIGxpbmUgPSAyLCBjZXggPSAxLjgpCgpgYGAKCgoKYGBge3J9CiMgVGhpcyBmYWlscyBmb3IgImNWZWdfbG5kX3N1bSIKIyBUaGUgcmVzdWx0IHdpbGwgYmUgdGhhdCBzb21lIG9mIHRoZSBjb2x1bW5zIGFyZSByZXBlYXRlZC4KCmlmIChmaWxlLmV4aXN0cygib2FhdF9ZQW5vbS5yZGF0YSIpKSB7CiAgbG9hZCgib2FhdF9ZQW5vbS5yZGF0YSIpCn0gZWxzZSB7CgpvYXRfdmFyX3NlbnNtYXRfWUFub20gPC0gbWF0cml4KE5BLCBucm93ID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSwgbmNvbCA9IG5jb2woWF9sZXZlbDEpKQoKZm9yKGkgaW4gMTpsZW5ndGgoeV9uYW1lc19zdW0pKXsKICAKICB5bmFtZSA8LSB5X25hbWVzX3N1bVtpXQogIHkgPC0gWUFub21fbGV2ZWwxWywgeW5hbWVdCiAgdHJ5KG9hdCA8LSB0d29TdGVwX3NlbnMoWCA9IFhfbGV2ZWwxLCB5ID0geSkpCiAgb2F0X3Zhcl9zZW5zbWF0X1lBbm9tW2ksIF0gPC0gb2F0Cn0KCnNhdmUoeV9uYW1lc19zdW0sIG9hdF92YXJfc2Vuc21hdF9ZQW5vbSwgZmlsZSA9ICJvYWF0X1lBbm9tLnJkYXRhIikKCn0KYGBgCgoKCmBgYHtyLCBmaWcud2lkdGg9IDEwLCBmaWcuaGVpZ2h0ID0gNn0KIyBub3JtYWxpemUgdGhlIHNlbnNpdGl2aXR5IG1hdHJpeApjb2xuYW1lcyhvYXRfdmFyX3NlbnNtYXRfWUFub20pIDwtIGNvbG5hbWVzKFhfbGV2ZWwxKQpyb3duYW1lcyhvYXRfdmFyX3NlbnNtYXRfWUFub20pIDwtIHlfbmFtZXNfc3VtCgojdGVzdCA8LSBub3JtYWxpemUodChvYXQudmFyLnNlbnNtYXQpKQoKI2ltYWdlKHRlc3QpCiNwYXIoKQpoZWF0bWFwKG9hdF92YXJfc2Vuc21hdF9ZQW5vbSwgUm93diA9IE5BLCBDb2x2ID0gTkEsIG1hciA9IGMoMTAsMTApLCBzY2FsZSA9ICdyb3cnKQpoZWF0bWFwKG9hdF92YXJfc2Vuc21hdF9ZQW5vbSwgbWFyID0gYygxMCw2KSwgc2NhbGUgPSAncm93JykKCmBgYAoKCmBgYHtyLCBmaWcud2lkdGggPTEyLCBmaWcuaGVpZ2h0ID0gN30KCm5vcm1zZW5zX1lBbm9tIDwtIG5vcm1hbGl6ZSh0KG9hdF92YXJfc2Vuc21hdF9ZQW5vbSkpCgpwYXIobWFyID0gYygxMiwxMiw1LDIpKQppbWFnZShub3Jtc2Vuc19ZQW5vbSwgYXhlcyA9IEZBTFNFLCBjb2wgPSBibHVlcykKYXhpcygxLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gcCksIGxhYmVscyA9IGNvbG5hbWVzKFhfbGV2ZWwxKSwgbGFzID0gMikKYXhpcygyLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSksIGxhYmVscyA9IHlfbmFtZXNfc3VtLCBsYXMgPSAxKQptdGV4dCgnT25lLWF0LWEtdGltZSBzZW5zaXRpdml0eSwgdmFyaWFuY2Ugb2YgaGlzdG9yaWNhbCBjaGFuZ2UgYWNyb3NzIGxldmVsIDEgZW5zZW1ibGUnLCBzaWRlID0gMywgYWRqID0gMCwgbGluZSA9IDIsIGNleCA9IDEuOCkKCmBgYAoKCiMjIFBsb3QgYm90aCBzZW5zaXRpdml0eSBtYXRyaWNlcyBvbiB0b3Agb2Ygb25lIGFub3RoZXIuCkl0IGxvb2tzIGFzIHRob3VnaCBib3RoIHRoZSBhYnNvbHV0ZSB2YWx1ZSBhbmQgdGhlIGNoYW5nZSBvdmVyIHRpbWUgYXJlIGNvbnRyb2xsZWQgYnkgdGhlIHNhbWUgcGFyYW1ldGVycy4KYGBge3IsIGZpZy53aWR0aCA9MTIsIGZpZy5oZWlnaHQgPSAxMn0KcGFyKG1mcm93ID0gYygyLDEpLCBtYXIgPSBjKDEyLDEyLDUsMikpCgppbWFnZShub3Jtc2Vuc19ZLCBheGVzID0gRkFMU0UsIGNvbCA9IGJsdWVzKQpheGlzKDEsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBwKSwgbGFiZWxzID0gY29sbmFtZXMoWF9sZXZlbDEpLCBsYXMgPSAyKQpheGlzKDIsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBsZW5ndGgoeV9uYW1lc19zdW0pKSwgbGFiZWxzID0geV9uYW1lc19zdW0sIGxhcyA9IDEpCm10ZXh0KCdPbmUtYXQtYS10aW1lIHNlbnNpdGl2aXR5LCB2YXJpYW5jZSBvZiBoaXN0b3JpY2FsIGNoYW5nZSBhY3Jvc3MgbGV2ZWwgMSBlbnNlbWJsZScsIHNpZGUgPSAzLCBhZGogPSAwLCBsaW5lID0gMiwgY2V4ID0gMS44KQoKCmltYWdlKG5vcm1zZW5zX1lBbm9tLCBheGVzID0gRkFMU0UsIGNvbCA9IGJsdWVzKQpheGlzKDEsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBwKSwgbGFiZWxzID0gY29sbmFtZXMoWF9sZXZlbDEpLCBsYXMgPSAyKQpheGlzKDIsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBsZW5ndGgoeV9uYW1lc19zdW0pKSwgbGFiZWxzID0geV9uYW1lc19zdW0sIGxhcyA9IDEpCm10ZXh0KCdPbmUtYXQtYS10aW1lIHNlbnNpdGl2aXR5LCB2YXJpYW5jZSBvZiBoaXN0b3JpY2FsIGNoYW5nZSBhY3Jvc3MgbGV2ZWwgMSBlbnNlbWJsZScsIHNpZGUgPSAzLCBhZGogPSAwLCBsaW5lID0gMiwgY2V4ID0gMS44KQoKCmBgYAoKCiMjIEhvdyBnb29kIGFyZSB0aGUgZW11bGF0b3JzIGZvciBlYWNoIG91dHB1dD8KVGhlIGVtdWxhdG9ycyBhcHBlYXIgdG8gYmUgYXQgbGVhc3QgY2FwdHVyaW5nIHRoZSBicm9hZCByZXNwb25zZSBmb3IgYWxsIG9mIHRoZSBvdXRwdXQgdmFyaWFibGVzLgoKRmlyc3QsIHBsb3QgdGhlIHN0cmFpZ2h0IGtyaWdpbmcgZW11bGF0b3JzCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA2LCByZXN1bHRzID0gJ2hpZGUnfQoKaWYgKGZpbGUuZXhpc3RzKCJrbV9lbXVsYXRvcnNfWS5yZGF0YSIpKSB7CiAgbG9hZCgia21fZW11bGF0b3JzX1kucmRhdGEiKQp9IGVsc2UgewogIAogIGVtbGlzdF9rbV9ZIDwtIHZlY3Rvcihtb2RlID0gJ2xpc3QnLCBsZW5ndGggPSBsZW5ndGgoeV9uYW1lc19zdW0pKQogIAogIGZvcihpIGluIDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSl7CiAgICB5bmFtZSA8LSB5X25hbWVzX3N1bVtpXQogICAgeSA8LSBZX2xldmVsMVssIHluYW1lXQogICAgCiAgICBlbSA8LSBrbSh+LiwgZGVzaWduID0gWF9sZXZlbDEsIHJlc3BvbnNlID0geSkKICAgIGVtbGlzdF9rbV9ZW1tpXV0gPC0gZW0KICB9CiAgCiAgbG9vbGlzdF9rbV9ZIDwtIHZlY3Rvcihtb2RlID0gJ2xpc3QnLCBsZW5ndGggPSBsZW5ndGgoeV9uYW1lc19zdW0pKQogIAogIGZvcihpIGluIDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSl7CiAgICAKICAgIGxvbyA8LSBsZWF2ZU9uZU91dC5rbShtb2RlbCA9IGVtbGlzdF9rbV9ZW1tpXV0sIHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSkKICAgIGxvb2xpc3Rfa21fWVtbaV1dIDwtIGxvbwogIH0KICAKICBzYXZlKGVtbGlzdF9rbV9ZLGxvb2xpc3Rfa21fWSwgZmlsZSA9ICJrbV9lbXVsYXRvcnNfWS5yZGF0YSIpCn0KCmBgYAoKYGBge3J9CgoKbG9vc3RhdHNfa21fWSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKCmZvcihpIGluIDE6bGVuZ3RoKGVtbGlzdF9rbV9ZKSl7CiAgCiAgbG9vc3RhdHMgPC0ga21Mb29TdGF0cyhlbWxpc3Rfa21fWVtbaV1dKQogIGxvb3N0YXRzX2ttX1lbW2ldXSA8LSBsb29zdGF0cwogIHByaW50KGxvb3N0YXRzJHBtYWUpCn0KCmBgYAoKCmBgYHtyLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDEyfQpwYXIobWZyb3cgPSBjKDQsNCksIG1hciA9IGMoMyw0LDIsMiksIG9tYSA9IGMoNCw0LDQsMC4xKSkKZm9yKGkgaW4gMTpsZW5ndGgobG9vbGlzdF9rbV9ZKSl7CiAgCiAgeSA8LSBZX2xldmVsMVssIHlfbmFtZXNfc3VtW2ldXQogIGxvbyA8LSBsb29saXN0X2ttX1lbW2ldXQogIHlsaW0gPC0gcmFuZ2UoYyhsb28kbWVhbiAtICgyKmxvbyRzZCksIGxvbyRtZWFuICsgKDIqbG9vJHNkKSkgKQogIHBsb3QoeSwgbG9vJG1lYW4sIHhsYWIgPSAnJywgeWxhYiA9ICcnLCBtYWluID0geV9uYW1lc19zdW1baV0gLCB5bGltID0geWxpbSwgY29sID0gbWFrZVRyYW5zcGFyZW50KCdibGFjaycsIDcwKSwKICAgICAgIHBjaCA9IDE5KQogIHNlZ21lbnRzKHgwID0geSwgeTAgPSBsb28kbWVhbiAtICgyKmxvbyRzZCkgICwgeDEgPSB5ICwgeTEgPSBsb28kbWVhbiArICgyKmxvbyRzZCksIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCkpCiAgYWJsaW5lKDAsMSkKICBsZWdlbmQoJ2JvdHRvbXJpZ2h0JyxsZWdlbmQgPSBwYXN0ZSgnbWFlID0nLHJvdW5kKGxvb3N0YXRzX2ttX1lbW2ldXSRwbWFlLDIpLCclJykgLCBidHkgPSAnbicpCgp9CgptdGV4dCgnQWN0dWFsJywgc2lkZSA9IDEsIGxpbmUgPSAxLCBvdXRlciA9IFRSVUUsIGNleCA9IDIgKQptdGV4dCgnUHJlZGljdGVkJywgc2lkZSA9IDIsIGxpbmUgPSAwLCBvdXRlciA9IFRSVUUsIGNleCA9IDIpIAptdGV4dCgnTW9kZXJuIFZhbHVlIChZKScsIHNpZGUgPSAzLCBsaW5lID0gMCwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyKSAKCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNiwgcmVzdWx0cyA9ICdoaWRlJ30KCmlmIChmaWxlLmV4aXN0cygia21fZW11bGF0b3JzX1lBbm9tLnJkYXRhIikpIHsKICBsb2FkKCJrbV9lbXVsYXRvcnNfWUFub20ucmRhdGEiKQp9IGVsc2UgewogIAogIGVtbGlzdF9rbV9ZQW5vbSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKICAKICBmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogICAgeW5hbWUgPC0geV9uYW1lc19zdW1baV0KICAgIHkgPC0gWUFub21fbGV2ZWwxWywgeW5hbWVdCiAgICAKICAgIGVtIDwtIGttKH4uLCBkZXNpZ24gPSBYX2xldmVsMSwgcmVzcG9uc2UgPSB5KQogICAgZW1saXN0X2ttX1lBbm9tW1tpXV0gPC0gZW0KICB9CiAgCiAgbG9vbGlzdF9rbV9ZQW5vbSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKICAKICBmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogICAgCiAgICBsb28gPC0gbGVhdmVPbmVPdXQua20obW9kZWwgPSBlbWxpc3Rfa21fWUFub21bW2ldXSwgdHlwZSA9ICdVSycsIHRyZW5kLnJlZXN0aW0gPSBUUlVFKQogICAgbG9vbGlzdF9rbV9ZQW5vbVtbaV1dIDwtIGxvbwogIH0KICAKICBzYXZlKGVtbGlzdF9rbV9ZQW5vbSxsb29saXN0X2ttX1lBbm9tLCBmaWxlID0gImttX2VtdWxhdG9yc19ZQW5vbS5yZGF0YSIpCn0KCmBgYAoKCiMga20gZW11bGF0b3JzIGZvciBjaGFuZ2UgaW4gdmFyaWFibGVzIG92ZXIgdGltZQoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTJ9CnBhcihtZnJvdyA9IGMoNCw0KSwgbWFyID0gYygzLDQsMiwyKSwgb21hID0gYyg0LDQsNCwwLjEpKQpmb3IoaSBpbiAxOmxlbmd0aChsb29saXN0X2ttX1lBbm9tKSl7CiAgCiAgeSA8LSBZQW5vbV9sZXZlbDFbLCB5X25hbWVzX3N1bVtpXV0KICBsb28gPC0gbG9vbGlzdF9rbV9ZQW5vbVtbaV1dCiAgeWxpbSA8LSByYW5nZShjKGxvbyRtZWFuIC0gKDIqbG9vJHNkKSwgbG9vJG1lYW4gKyAoMipsb28kc2QpKSApCiAgcGxvdCh5LCBsb28kbWVhbiwgeGxhYiA9ICcnLCB5bGFiID0gJycsIG1haW4gPSB5X25hbWVzX3N1bVtpXSAsIHlsaW0gPSB5bGltLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApLAogICAgICAgcGNoID0gMTkpCiAgc2VnbWVudHMoeDAgPSB5LCB5MCA9IGxvbyRtZWFuIC0gKDIqbG9vJHNkKSAgLCB4MSA9IHkgLCB5MSA9IGxvbyRtZWFuICsgKDIqbG9vJHNkKSwgY29sID0gbWFrZVRyYW5zcGFyZW50KCdibGFjaycsIDcwKSkKICBhYmxpbmUoMCwxKQogIAoKfQoKbXRleHQoJ0FjdHVhbCcsIHNpZGUgPSAxLCBsaW5lID0gMSwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyICkKbXRleHQoJ1ByZWRpY3RlZCcsIHNpZGUgPSAyLCBsaW5lID0gMCwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyKSAKbXRleHQoJ0NoYW5nZSBvdmVyIHRpbWUgKFlBbm9tKScsIHNpZGUgPSAzLCBsaW5lID0gMSwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyKSAKCmBgYAoKTmV4dCwgcGxvdCB0aGUgdHdvc3RlcCBnbG1uZXQva20gZW11bGF0b3JzCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA2fQojIFR3b3N0ZXAgZ2xtbmV0IGVtdWxhdG9ycwoKaWYgKGZpbGUuZXhpc3RzKCJ0c19lbXVsYXRvcnNfWS5yZGF0YSIpKSB7CiAgbG9hZCgidHNfZW11bGF0b3JzX1kucmRhdGEiKQp9IGVsc2UgewogIAogIGVtbGlzdF90d29TdGVwX2dsbW5ldF9ZIDwtIHZlY3Rvcihtb2RlID0gJ2xpc3QnLCBsZW5ndGggPSBsZW5ndGgoeV9uYW1lc19zdW0pKQogIAogIGZvcihpIGluIDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSl7CiAgICAKICAgIHluYW1lIDwtIHlfbmFtZXNfc3VtW2ldCiAgICB5IDwtIFlfbGV2ZWwxWywgeW5hbWVdCiAgICAKICAgIGVtIDwtIHR3b1N0ZXBfZ2xtbmV0KFggPSBYX2xldmVsMSwgeSA9IHkpCiAgICBlbWxpc3RfdHdvU3RlcF9nbG1uZXRfWVtbaV1dIDwtIGVtCiAgfQogIAogIGxvb2xpc3RfdHdvU3RlcF9nbG1uZXRfWSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKICAKICBmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogICAgCiAgICBsb28gPC0gbGVhdmVPbmVPdXQua20obW9kZWwgPSBlbWxpc3RfdHdvU3RlcF9nbG1uZXRfWVtbaV1dJGVtdWxhdG9yLCB0eXBlID0gJ1VLJywgdHJlbmQucmVlc3RpbSA9IFRSVUUpCiAgICBsb29saXN0X3R3b1N0ZXBfZ2xtbmV0X1lbW2ldXSA8LSBsb28KICB9CiAgCiAgCiAgCiAgc2F2ZShlbWxpc3RfdHdvU3RlcF9nbG1uZXRfWSwgbG9vbGlzdF90d29TdGVwX2dsbW5ldF9ZLCBmaWxlID0gInRzX2VtdWxhdG9yc19ZLnJkYXRhIikKCn0KCgpgYGAKCmBgYHtyfQojIENhbiBnZXQgbnVtZXJpY2FsIHBlcmZvcm1hbmNlIHVzaW5nCgpsb29zdGF0c190d29TdGVwX2dsbW5ldF9ZIDwtIHZlY3Rvcihtb2RlID0gJ2xpc3QnLCBsZW5ndGggPSBsZW5ndGgoeV9uYW1lc19zdW0pKQoKZm9yKGkgaW4gMTpsZW5ndGgoZW1saXN0X3R3b1N0ZXBfZ2xtbmV0X1kpKXsKICAKICBsb29zdGF0cyA8LSBrbUxvb1N0YXRzKGVtbGlzdF90d29TdGVwX2dsbW5ldF9ZW1tpXV0kZW11bGF0b3IpCiAgbG9vc3RhdHNfdHdvU3RlcF9nbG1uZXRfWVtbaV1dIDwtIGxvb3N0YXRzCiAgcHJpbnQobG9vc3RhdHMkcG1hZSkKfQoKCmBgYAoKCgojIyBUd29TdGVwIGVtdWxhdG9yIHBlcmZvcm1hbmNlIGZvciBtb2Rlcm4gdmFsdWVzCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KcGFyKG1mcm93ID0gYyg0LDQpLCBtYXIgPSBjKDMsNCwyLDIpLCBvbWEgPSBjKDQsNCw0LDAuMSkpCmZvcihpIGluIDE6bGVuZ3RoKGxvb2xpc3RfdHdvU3RlcF9nbG1uZXRfWSkpewogIAogIHkgPC0gWV9sZXZlbDFbLCB5X25hbWVzX3N1bVtpXV0KICBsb28gPC0gbG9vbGlzdF90d29TdGVwX2dsbW5ldF9ZW1tpXV0KICB5bGltIDwtIHJhbmdlKGMobG9vJG1lYW4gLSAoMipsb28kc2QpLCBsb28kbWVhbiArICgyKmxvbyRzZCkpICkKICBwbG90KHksIGxvbyRtZWFuLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IHlfbmFtZXNfc3VtW2ldICwgeWxpbSA9IHlsaW0sIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCksCiAgICAgICBwY2ggPSAxOSkKICBzZWdtZW50cyh4MCA9IHksIHkwID0gbG9vJG1lYW4gLSAoMipsb28kc2QpICAsIHgxID0geSAsIHkxID0gbG9vJG1lYW4gKyAoMipsb28kc2QpLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApKQogIGFibGluZSgwLDEpCiAgbGVnZW5kKCdib3R0b21yaWdodCcsbGVnZW5kID0gcGFzdGUoJ21hZSA9Jyxyb3VuZChsb29zdGF0c190d29TdGVwX2dsbW5ldF9ZW1tpXV0kcG1hZSwyKSwnJScpICwgYnR5ID0gJ24nKQoKfQoKbXRleHQoJ0FjdHVhbCcsIHNpZGUgPSAxLCBsaW5lID0gMSwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyICkKbXRleHQoJ1ByZWRpY3RlZCcsIHNpZGUgPSAyLCBsaW5lID0gMCwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyKSAKbXRleHQoJ01vZGVybiBWYWx1ZSAoWSknLCBzaWRlID0gMywgbGluZSA9IDAsIG91dGVyID0gVFJVRSwgY2V4ID0gMikgCgpgYGAKCiMgQ29tcGFyZSBMZWF2ZS1vbmUtb3V0IHN0YXRpc3RpY3MgZm9yIHRoZSB0d28gdHlwZXMgb2YgZW11bGF0b3IKCldlIHVzZSB0aGUgbGVhdmUtb25lLW91dCBNZWFuIEFic29sdXRlIEVycm9yLCBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSByYW5nZSBvZiB0aGUgb3V0cHV0IGFjcm9zcyB0aGUgZW5zZW1ibGUuIFdlIGZpbmQgdGhhdCB0aGUgdHdvc3RlcCBlbXVsYXRvcmlzbid0IHNpZ25pZmljYW50bHkgbW9yZSBhY2N1cmF0ZSwgYW5kIGlzIGluZGVlZCAqbGVzcyogYWNjdXJhdGUgZm9yIHRyZWUgZnJhY3Rpb24uCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDd9CgoKa21fcG1hZSA8LSBzYXBwbHkobG9vc3RhdHNfa21fWSwgJ1tbJywgJ3BtYWUnKQp0c19wbWFlIDwtIHNhcHBseShsb29zdGF0c190d29TdGVwX2dsbW5ldF9ZLCAnW1snLCAncG1hZScpCgpwYXIobWFyID0gYygxMiw0LDIsMSksIGxhcyA9MSApCnBsb3QoMTpsZW5ndGgoeV9uYW1lc19zdW0pLCBrbV9wbWFlLAogICAgIHlsaW0gPSBjKDAsMTUpLCBwY2ggPSAxOSwKICAgICBheGVzID0gRkFMU0UsIHhsYWIgPSAnJywgCiAgICAgeWxhYiA9ICdMT08gTUFFICglIG9mIHJhbmdlKScsCiAgICAgY2V4ID0gMS4yKQpwb2ludHMoMTpsZW5ndGgoeV9uYW1lc19zdW0pLHRzX3BtYWUgLCBjb2w9ICdyZWQnLCBwY2ggPSAxOSwgY2V4ID0gMS4yKQpsZWdlbmQoJ3RvcGxlZnQnLCBjKCdrbSBlbXVsYXRvcicsICd0d29TdGVwIGVtdWxhdG9yJyksIHBjaCA9IDE5LCBjb2wgPSBjKCdibGFjaycsICdyZWQnKSwgcHQuY2V4ID0gMS4yKQpheGlzICgyKQpwYXIobGFzID0gMikKYXhpcygxLCBhdCA9IDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSwgbGFiZWxzID0geV9uYW1lc19zdW0pCgpgYGAKCgoKYGBge3J9CgojIFdyaXRlIGFuIGVtdWxhdG9yIHdyYXBwZXIKCiMgV3JpdGUgYSBsZWF2ZS1vbmUtb3V0IHdyYXBwZXIKCiMgQ3JlYXRlIGEgbGlzdCBvZiBlbXVsYXRvciBmaXRzLCBmb3IgYm90aCBrbSBhbmQgdHdvU3RlcCBtZXRob2RzLgojIFVzZSBtY2xhcHBseSB0byBidWlsZCB0aGUgbGlzdHMKIyB1c2UgY29kZSBmcm9tIEhERSBwYWNrYWdlCiMgTWFrZSBzdXJlIGVycm9ycyBhcmUgaGFuZGxlZCBhZGVxdWF0ZWx5LgoKCiMgQ2FuIHdlIHdyaXRlIGl0IHRvIHVzZSBhbnkgZW11bGF0b3I/IChpLmUga20sIHR3b3N0ZXAsIHNvbWV0aGluZyBmcm9tIGFub3RoZXIgcGFja2FnZT8pCmBgYAoKCgojIEhpc3RvcnkgbWF0Y2hpbmcgYW5kIGdlbmVyYXRpb24gb2YgbmV3IGVuc2VtYmxlIG1lbWJlcnMKVG8gdXNlIEhpc3RvcnkgTWF0Y2hpbmcsIHdlIG5lZWQgdG8gc3BlY2lmeSB0YXJnZXRzIGZvciB2YXJpb3VzIG1vZGVsIG91dHB1dHMuIFdlIHRyZWF0IHRoZXNlIHRhcmdldHMgYXMgIm9ic2VydmF0aW9ucyIgd2l0aCBhbiB1bmNlcnRhaW50eSB3aGVyZSBhIG1vZGVsIHJ1biBtYXJrZWQgYXMgImltcGxhdXNpYmxlIiAoYmV5b25kIDNzZCkgbWF0Y2hlcyB0aGUgaGFyZCBib3VuZGFyaWVzIHByZXZpb3VzbHkgaWRlbnRpZmllZCBieSBBLiBXaWx0c2hpcmUgYXMgYmVpbmcgZGVzaXJhYmxlLgoKQ2hvb3NlIHRoZSBjZW50cmUgb2YgdGhlIChpbXBsaWVkKSB1bmlmb3JtIGRpc3RyaWJ1dGlvbi4KIGNzX2diLnRhcmdldCA9ICgzMDAwIC0gNzUwKSAvIDIgPSAgMTEyNQogY3YudGFyZ2V0ID0gKDgwMCAtIDMwMCkgLyAyID0gMjUwCiBucHBfbl9nYi50YXJnZXQgPSAoODAgLSAzNSkgLyAyID0gMjIuNQoKIG5icC50YXJnZXQgPSAwCiAoZ3BwLnRhcmdldCA9IDc1KQogKHJ1bm9mZi50YXJnZXQgPSAxKQogCih0byBkbzogdmlzdWFsaXNlIGltcGxhdXNpYmlsaXR5IG9mIGRlc2lnbiBhbmQgbG9vIGVtdWxhdGVkIHZhbHVlcyBvZiBkZXNpZ24gYXMgaGlzdG9ncmFtKSAKCmBgYHtyfQoKI1kudGFyZ2V0ID0gYyhjc19nYi50YXJnZXQsIGN2LnRhcmdldCwgbnBwX25fZ2IudGFyZ2V0LCBydW5vZmYudGFyZ2V0LCBuYnAudGFyZ2V0KQoKeW5hbWVzX2NvbnN0IDwtIGMoJ25icF9sbmRfc3VtJywgJ25wcF9ubGltX2xuZF9zdW0nLCAnY1NvaWxfbG5kX3N1bScsICdjVmVnX2xuZF9zdW0nKQp5dW5pdHNfY29uc3QgPC0gYygnR3RDL3llYXInLCAnR3RDL3llYXInLCAnR3RDJywgJ0d0QycpCllfY29uc3RfbGV2ZWwxYSA8LSBZX2xldmVsMWFbLCB5bmFtZXNfY29uc3RdCgpzY2FsZXZlYyA8LSBjKDFlMTIveXNlYywgMWUxMi95c2VjLCAxZTEyLCAxZTEyKQpZX2NvbnN0X2xldmVsMWFfc2NhbGVkIDwtIHN3ZWVwKFlfY29uc3RfbGV2ZWwxYSwgMiwgU1RBVFMgPSBzY2FsZXZlYywgRlVOID0gJy8nICkKCiMgVGhpcyBpcyBhICJub3JtYWxpc2F0aW9uIHZlY3RvciIsIGZvciBtYWtpbmcgdGhlIG91dHB1dCBudW1iZXJzIG1vcmUgbWFuYWdlYWJsZS4KI2NzX2diICAgICAgIGN2ICAgIGdwcF9nYiAgICAgICAgbmJwIG5wcF9uX2diICAgIHJ1bm9mZgpub3JtX3ZlYyA9IGMoMWUxMiwgMWUxMiwgMWUxMi95c2VjICwgMWUxMiwgMWUxMiwgMWU5KQoKIyBuYnAgIG5wcCAgY3NvaWwgIGN2ZWcKWV9sb3dlciA8LSBjKC0xMCwgMzUsIDc1MCwgMzAwKQpZX3VwcGVyIDwtIGMoMTAsIDgwLCAzMDAwLCA4MDApCgojIEknbSBnb2luZyB0byBzZXQgaXQgc28gdGhhdCArIDRzZCBhbGlnbnMgYXBwcm94aW1hdGVseSB3aXRoIHRoZSBvcmlnaW5hbCBsaW1pdHMKIyBnaXZlbiBieSBBbmR5IFdpbHRzaGlyZS4gVGhpcyBnaXZlcyByb29tIGZvciB1bmNlcnRhaW50eSBmcm9tIHRoZSBlbXVsYXRvcgpZX3RhcmdldCA9IFlfdXBwZXIgLSAoYWJzKFlfdXBwZXIgLSAoWV9sb3dlcikpIC8gMiApIyBhYnMoKSB0byBmaXggdGhlIHByb2JsZW0gd2l0aCBuZWdhdGl2ZSBudW1iZXJzCgoKIyBzdGFuZGFyZCBkZXZpYXRpb24gaXMgZGVyaXZlZCBmcm9tIHRoZSBsaW1pdHMgYW5kIHRoZSBjZW50cmFsIHRhcmdldAojICh0aGlzIGRpc3RhbmNlIGlzIGFzc3VtZWQgdG8gYmUgNCBzdGFuZGFyZCBkZXZpYXRpb25zLgpZX3NkID0gKFlfdXBwZXIgLSBZX3RhcmdldCkgLyA0Cm5hbWVzKFlfc2QpID0gY29sbmFtZXMoWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkKCgpwID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKQoKb2JzX3NkX2xpc3QgPSBhcy5saXN0KHJlcCgwLjAxLHApKQpkaXNjX2xpc3QgPSAgYXMubGlzdChyZXAoMCxwKSkgCmRpc2Nfc2RfbGlzdCA9ICBhcy5saXN0KFlfc2QpCnRocmVzID0gMwoKbWluc19hdWcgPSBhcHBseShYX2xldmVsMWEsIDIsIEZVTiA9IG1pbikKbWF4ZXNfYXVnID1hcHBseShYX2xldmVsMWEsIDIsIEZVTiA9IG1heCkKCiMgY29udmVydCBZX3RhcmdldCBmb3IgaW5nZXN0aW9uIGludG8gZnVuY3Rpb24KWV90YXJnZXQgPSBtYXRyaXgoWV90YXJnZXQsIG5yb3cgPSAxKQoKYGBgCgoKIyMgdmlzdWFsaXNlIHRoZSBjb25zdHJhaW50cwpgYGB7cn0KCiMgSGlzdG9ncmFtIG9mIGxldmVsIDEgY29uc3RyYWludHMKaGNvbCA9ICdkYXJrZ3JleScKbGNvbCA9ICdibGFjaycKcGFyKG1mcm93ID0gYygyLDIpLCBmZyA9ICdkYXJrZ3JleScsIGxhcyA9IDEpCgoKCmhpc3QoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25icF9sbmRfc3VtJ10sIGNvbCA9IGhjb2wsIG1haW4gPSAnTkJQJywgeGxhYiA9ICdHdEMveWVhcicpCnBvbHlnb24oeCA9IGMoLTEwLCAxMDAsIDEwMCwgLTEwKSwgeSA9IGMoMCwgMCwgMTAwMCwgMTAwMCksCiAgICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJyksCiAgICAgICAgYm9yZGVyID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJykpCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCducHBfbmxpbV9sbmRfc3VtJ10sIGNvbCA9IGhjb2wgLCBtYWluID0gJ05QUCcsIHhsYWIgPSAnR3RDL3llYXInKQpwb2x5Z29uKHggPSBjKDM1LCA4MCwgODAsIDM1KSwgeSA9IGMoMCwgMCwgMTAwMCwgMTAwMCksCiAgICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJyksCiAgICAgICAgYm9yZGVyID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJykpCgoKICAgICAgICBoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10sIGNvbCA9IGhjb2wsIG1haW4gPSAnU29pbCBDYXJib24nLCB4bGFiID0gJ0d0QycpCnBvbHlnb24oeCA9IGMoNzUwLCAzMDAwLCAzMDAwLCA3NTApLCB5ID0gYygwLCAwLCAxMDAwLCAxMDAwKSwKICAgICAgICBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSwKICAgICAgICBib3JkZXIgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSkKCmhpc3QoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddLCBjb2wgPSBoY29sLCBtYWluID0gJ1ZlZ2V0YXRpb24gQ2FyYm9uJywgeGxhYiA9ICdHdEMnKQpwb2x5Z29uKHggPSBjKDMwMCwgODAwLCA4MDAsIDMwMCksIHkgPSBjKDAsIDAsIDEwMDAsIDEwMDApLAogICAgICAgIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpLAogICAgICAgYm9yZGVyID0gIG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpKQoKYGBgCgojIyBUaW1lc2VyaWVzIHRoYXQgbWF0Y2ggdGhlIGNvbnN0cmFpbnRzLgpQbG90IHRoZSBvcmlnaW5hbCBlbnNlbWJsZSwgcGx1cyB0aGUgc3R1ZmYgdGhhdCBtYXRjaGVzIHRoZSBjb25zdHJhaW50cy4gSW5jbHVkZSBhbm9tYWxpZXMuCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA5fQoKIyByZW1vdmUgdG8gbGV2ZWwgMWEgUmVsYXRpdmUgdG8gdG9wbGV2ZWxfaXgKdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXggPC0odG9wbGV2ZWxfaXhbLVlfbmxldmVsMF9peF0pW2xldmVsMWFfaXhdCgojIFNvIGZ1cnRoZXIgY29uc3RyYWluaW5nIHRvIGxldmVsIDIgY2FuIGJlIGFzc29jaWF0ZWQgYmFjayB0byB0aGUgdG9wIGxldmVsLgoKbGV2ZWwyX2l4ID0gd2hpY2goWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25icF9sbmRfc3VtJ10gPiAtMTAgJgogICAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCducHBfbmxpbV9sbmRfc3VtJ10gPiAzNSAmICBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddIDwgODAgJgogICAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10gPiA3NTAgJiBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddIDwgMzAwMCAmCiAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSA+IDMwMCAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSA8IDgwMAogICkKYGBgCgoKV2UgZmluZCB0aGF0IGFkZGluZyBhIGNvbnN0cmFpbnQgdG8gbGV2ZWwgMiBjb25zdHJhaW5zIHRoZSBiZWhhdmlvdXIgb2YgdGhlIHNvaWwgY2FyYm9uIHBvb2wsIGJ1dCBub3QgdGhlIHZlZ2V0YXRpb24gY2FyYm9uIHBvb2wuIFByb2JhYmx5IG5vdCBhIHN1cnByaXNlLCBnaXZlbiB0aGUgU29pbCBDYXJib24gcG9vbCAoYW5kIGNoYW5nZXMpIGFyZSBtdWNoIGxhcmdlciB0aGFuIHRoZSB2ZWdldGF0aW9uIGNhcmJvbiBwb29sLgoKYGBge3IgdmVnQy1zb2lsQy1jb25zdHJhaW5lZCwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA4fQojY1NvaWxfZW5zX2Fub20gW3RvcGxldmVsX3RvX2xldmVsXzFhX2l4LCBdCgpwYXIobWZyb3c9IGMoMSw0KSwgbGFzID0gMSkKCnBsb3Rjb2wgPC0gYyhtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApKQpvdmVycGxvdGNvbCA8LSBjKG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMycsIDIwMCkpCgoKeWxpbSA9IHJhbmdlKGNTb2lsX2VucykKbWF0cGxvdCh5ZWFycywgdChjU29pbF9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdjU29pbCcsCiAgICAgICAgYnR5ID0gJ24nKQptYXRsaW5lcyggeWVhcnMsIHQoKGNTb2lsX2Vuc1t0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSxjb2wgPSBvdmVycGxvdGNvbCwgIGx3ZCA9IDEuNSwgbHR5ID0gJ3NvbGlkJykKCnlsaW0gPSByYW5nZShjU29pbF9lbnMpCm1hdHBsb3QoeWVhcnMsIHQoY1ZlZ19lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdjVmVnJywKICAgICAgICBidHkgPSAnbicpCm1hdGxpbmVzKCB5ZWFycywgdCgoY1ZlZ19lbnNbdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXgsIF0pW2xldmVsMl9peCwgXSksIGNvbCA9IG92ZXJwbG90Y29sLCBsd2QgPSAxLjUsIGx0eSA9ICdzb2xpZCcpCgoKCnlsaW0gPSByYW5nZShjU29pbF9lbnNfYW5vbSkKbWF0cGxvdCh5ZWFycywgdChjU29pbF9lbnNfYW5vbSksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ2NTb2lsIEFub21hbHknLAogICAgICAgIGJ0eSA9ICduJykKbWF0bGluZXMoIHllYXJzLCB0KChjU29pbF9lbnNfYW5vbVt0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSxjb2wgPSBvdmVycGxvdGNvbCwgbHdkID0gMS41LCBsdHkgPSAnc29saWQnKQoKCnlsaW0gPSByYW5nZShjU29pbF9lbnNfYW5vbSkKbWF0cGxvdCh5ZWFycywgdChjVmVnX2Vuc19hbm9tKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnY1ZlZyBBbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCm1hdGxpbmVzKCB5ZWFycywgdCgoY1ZlZ19lbnNfYW5vbVt0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSxjb2wgPSBvdmVycGxvdGNvbCxsd2QgPSAxLjUsIGx0eSA9ICdzb2xpZCcpCgpgYGAKCiMjIFRvdGFsIGxhbmQgY2FyYm9uIGNoYW5nZQoKV2UgcGxvdCB0aGUgSlVMRVMgdG90YWwgbGFuZCBjYXJib24gY2hhbmdlIGZyb20gMTg1MCwgdG9nZXRoZXIgd2l0aCAib2JzZXJ2YXRpb25zIiBmcm9tIHRoZSBHbG9iYWwgQ2FyYm9uIEJ1ZGdldCAoRnJpZWRsaWdzdGVpbiBldCBhbCwgMjAyMCkuIFRoZSAib2JzZXJ2YXRpb25zIGFyZSB0aGUgY3VtdWxhdGl2ZSBzdW0gb2YgdGhlICdsYW5kIHNpbmsnIGNvbHVtbiBvbiB0aGUgImhpc3RvcmljYWwgb2JzZXJ2YXRpb25zIHRhYiBvZiB0aGUgZGF0YSBmcm9tIHRoZSBwYXBlci4gSXQgc3RhdGVzICJUaGUgbGFuZCBzaW5rIGlzIHRoZSBhdmVyYWdlIG9mIHNldmVyYWwgZHluYW1pYyBnbG9iYWwgdmVnZXRhdGlvbiBtb2RlbHMgdGhhdCByZXByb2R1Y2UgdGhlIG9ic2VydmVkIG1lYW4gdG90YWwgbGFuZCBzaW5rIG9mIHRoZSAxOTkwcy4iCgpgYGB7ciB0b3RhbC1sYW5kLWNhcmJvbi1jaGFuZ2UsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gOH0KCnBhcihtZnJvdz0gYygxLDIpLCBsYXMgPSAxKQoKeWxpbSA9IHJhbmdlKHRvdGFsX2xhbmRfY2FyYm9uX2VucykKbWF0cGxvdCh5ZWFycywgdCh0b3RhbF9sYW5kX2NhcmJvbl9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdUb3RhbCBsYW5kIGNhcmJvbicsCiAgICAgICAgYnR5ID0gJ24nKQptYXRsaW5lcyggeWVhcnMsIHQoKHRvdGFsX2xhbmRfY2FyYm9uX2Vuc1t0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSwgY29sID0gb3ZlcnBsb3Rjb2wsIGx0eSA9ICdzb2xpZCcsIGx3ZCA9IDEuNSkKCnlsaW0gPSByYW5nZSh0b3RhbF9sYW5kX2NhcmJvbl9hbm9tKQptYXRwbG90KHllYXJzLCB0KHRvdGFsX2xhbmRfY2FyYm9uX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdUb3RhbCBsYW5kIGNhcmJvbiBhbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCm1hdGxpbmVzKCB5ZWFycywgdCgodG90YWxfbGFuZF9jYXJib25fYW5vbVt0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSwgY29sID0gb3ZlcnBsb3Rjb2wsIGx0eSA9ICdzb2xpZCcsIGx3ZCA9IDEuNSkKCiNBbm9tYWxpemUgaGlzdG9yaWNhbCBvYnNlcnZhdGlvbnMgdG8gMTg1MCAtIDE4NzAKaGlzdG9yaWNhbF90b3RhbF9sYW5kX2NhcmJvbl9vYnMgPC0gY3Vtc3VtKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRgbGFuZCBzaW5rYCkKaGlzdG9yaWNhbF90b3RhbF9sYW5kX2NhcmJvbl9vYnNfYW5vbSA8LSBoaXN0b3JpY2FsX3RvdGFsX2xhbmRfY2FyYm9uX29icyAtIGhpc3RvcmljYWxfdG90YWxfbGFuZF9jYXJib25fb2JzW3doaWNoKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyICVpbiUgMTg1MDoxODcwKV0KCmxpbmVzKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyLGhpc3RvcmljYWxfdG90YWxfbGFuZF9jYXJib25fb2JzX2Fub20sIHR5cGUgPSAnbCcsY29sID0gJ2JsdWUnLCBsd2QgPSAyKQpsZWdlbmQoJ3RvcGxlZnQnLCBsZWdlbmQgPSBjKCdSdWxlZCBvdXQnLCAnTGV2ZWwxYSBjb25zdHJhaW50JywgJ2hpc3RvcmljYWwnKSwgY29sID0gYygnYmxhY2snLCBvdmVycGxvdGNvbCwgJ2JsdWUnKSwKICAgICAgIGx3ZCA9IGMoMSwxLjUsMiksIGx0eSA9ICdzb2xpZCcpCgoKYGBgCgojIyMgTGFuZCBjYXJib24gU2luaz8KCkkgdGhpbmsgdG8gbWFrZSBhIGZhaXIgY29tcGFyaXNvbiwgd2UgbWlnaHQgbmVlZCB0byB0YWtlIHRoZSBkaWZmIG9mIHRoZSBhbm9tYWx5IChvciBqdXN0IHRoZSB0aW1lc2VyaWVzKSwgYXMgdGhlIGFib3ZlIHJlcHJlc2VudHMgdGhlIHRvdGFsIGNoYW5nZSBzaW5jZSAxODUwLCBhbmQgSSB0aGluayBhbGwgdGhlICJsYW5kIHNpbmsiIHN0dWZmIGxvb2tzIGF0IHRoZSB5ZWFyLXRvLXllYXIgY2hhbmdlcy4KCmBgYHtyIHRvdGFsLWxhbmQtY2FyYm9uLXNpbmssIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQoKCmxhbmRzaW5rX2VucyA8LSBtYXRyaXgoTkEsIG5yb3cgPSBucm93KHRvdGFsX2xhbmRfY2FyYm9uX2VucyksIG5jb2wgPSBuY29sKHRvdGFsX2xhbmRfY2FyYm9uX2VucyktMSkKCmZvcihpIGluIDE6bnJvdyhsYW5kc2lua19lbnMpKXsKICAKICBsYW5kc2lua19lbnNbaSwgXSA8LSBkaWZmKHRvdGFsX2xhbmRfY2FyYm9uX2Vuc1tpLCBdKQp9CgoKeWxpbSA9IHJhbmdlKGxhbmRzaW5rX2VucykKbWF0cGxvdCh5ZWFyc1stMV0sIHQobGFuZHNpbmtfZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwgeGxhYiA9ICcnLAogICAgICAgIHlsYWIgPSAnR3RDL3llYXInLCBtYWluID0gJ1RvdGFsIGxhbmQgY2FyYm9uIHNpbmsnLAogICAgICAgIGJ0eSA9ICduJykKbWF0bGluZXMoIHllYXJzWy0xXSwgdCgobGFuZHNpbmtfZW5zW3RvcGxldmVsX3RvX2xldmVsXzFhX2l4LCBdKVtsZXZlbDJfaXgsIF0pLCBjb2wgPSAndG9tYXRvMycsIGx0eSA9ICdzb2xpZCcpCgpsaW5lcyhoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kIHNpbmtgLCBjb2wgPSAnYmx1ZScsIGx3ZCA9IDIsIHhsYWIgPSAnJykKbGVnZW5kKCdib3R0b21sZWZ0JywgbGVnZW5kID0gYygnUnVsZWQgb3V0JywnbGV2ZWwgMWEgY29uc3RyYWluZWQnLCdoaXN0b3JpY2FsJyksIGNvbCA9IGMoJ2JsYWNrJywndG9tYXRvMycsICdibHVlJyApLCBsdHkgPSdzb2xpZCcsCiAgICAgICBsd2QgPSBjKDEsMSwyKSkKCgpgYGAKCgojIyMgSWRlbnRpZnkgcGFydHMgb2YgcGFyYW1ldGVyIHNwYWNlIHdoZXJlIHRoZSBsYW5kIGNhcmJvbiBzaW5rIGlzIGF0IGl0cyBtYXhpbXVtCldoYXQgZG8gdGhlc2UgcGFydHMgb2YgcGFyYW1ldGVyIHNwYWNlIHRlbGwgdXMgYWJvdXQgd2hhdCB3ZSBuZWVkIHRvIGRvIHRvIGhhdmUgdGhlIG1vZGVsIHJlcHJvZHVjZSByZWFsaXR5PwpgYGB7cn0KCiMgQnVpbGQgYW4gZW11bGF0b3IgZm9yIHRvdGFsIGxhbmQgY2FyYm9uIHVwdGFrZSBhdCB0aGUgZW5kIG9mIHRoZSBjZW50dXJ5CgoKIyBlbnNlbWJsZSBvZiBtb2Rlcm4gbGFuZHNpbmsKbGFuZHNpbmtfbW9kZXJuX2l4IDwtIHdoaWNoKHllYXJzWy0xXSAlaW4lIDE5OTQ6MjAxMykKCmxhbmRzaW5rX21vZGVybl9lbnMgPC0gKGFwcGx5KGxhbmRzaW5rX2Vuc1ssIGxhbmRzaW5rX21vZGVybl9peF0sIDEsIG1lYW4pKQoKbGFuZHNpbmtfbW9kZXJuX2Vuc19sZXZlbDFhIDwtIGxhbmRzaW5rX21vZGVybl9lbnNbdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXhdCgojIG9ic2VydmF0aW9ucyBvZiBtb2Rlcm4gbGFuZCBzaW5rCgpoaXN0X2l4IDwtIHdoaWNoKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyICVpbiUgMTk5NDoyMDEzKQpsYW5kc2lua19tb2Rlcm5fb2JzIDwtIG1lYW4oaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kIHNpbmtgW2hpc3RfaXggXSkKCiMgVGhpcyBpcyBhbGwgNDk5IG1lbWJlcnMKbGFuZHNpbmtfbW9kZXJuX2VyciA8LSBsYW5kc2lua19tb2Rlcm5fZW5zIC0gbGFuZHNpbmtfbW9kZXJuX29icwoKbGFuZHNpbmtfbW9kZXJuX2Vycl9sZXZlbDFhIDwtIGxhbmRzaW5rX21vZGVybl9lcnJbdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXhdIwoKCgojW2xldmVsMl9peCwgXQoKIyBCdWlsZCBlbXVsYXRvcnMgCgojIElkZW50aWZ5IHRoZSBwYXJ0cyBvZiBwYXJhbWV0ZXIgc3BhY2Ugd2hlcmUgdGhlIGRpZmZlcmVuY2VzIGFyZSBsb3cKCgojIEFyZSB3ZSBnZXR0aW5nIGNsb3NlIGZvciB0aGUgcmlnaHQgcmVhc29ucz8gV2hhdCBlbHNlIGlzIGdvaW5nIHdyb25nPwoKCgoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNn0KCgpwYXIobWZyb3cgPSBjKDQsOCksIG1hciA9IGMoMywyLDIsMSkpCmZvcihpIGluIDE6ZCl7CiAgCiAgcGxvdChYX2xldmVsMWFbLCBpXSxsYW5kc2lua19tb2Rlcm5fZXJyX2xldmVsMWEsICkKICAKfQoKCmBgYAoKYGBge3J9CgoKZml0X2xhbmRzaW5rX2VyciA8LSBrbSh+LixkZXNpZ24gPSBYX2xldmVsMWEsIHJlc3BvbnNlID0gIGxhbmRzaW5rX21vZGVybl9lcnJfbGV2ZWwxYSkKCgpgYGAKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA4fQoKcGxvdChmaXRfbGFuZHNpbmtfZXJyKQoKYGBgCgojIyMgd2hhdCBwYXJ0cyBvZiBwYXJhbWV0ZXIgc3BhY2UgYXJlIHRoZSBjbG9zZXN0PwpgYGB7cn0KCiMgVHdvIHN0cmF0ZWdpZXMgLSBwbG90IGxhbmQgc2luayBlcnJvciBhZ2FpbnN0IHBhcmFtZXRlcnMsIGFuZCBpZGVudGlmeSBiaXRzIG9mIHBhcmFtZXRlciBzcGFjZSB3aXRoIHNtYWxsZXN0IGVycm9yCgojbG93X2Vycm9yX2l4IDwtIGxhbmRzaW5rX21vZGVybl9lcnJfbGV2ZWwxYQoKCm1pbnMgPC0gYXBwbHkoWF9sZXZlbDFhLDIsRlVOID0gbWluKQptYXhlcyA8LSBhcHBseShYX2xldmVsMWEsMixGVU4gPSBtYXgpCiAgCm5zYW1wX3VuaWYgPC0gMTAwMDAwICAKWF91bmlmIDwtIHNhbXBfdW5pZihuc2FtcF91bmlmLCBtaW5zID0gbWlucywgbWF4ZXMgPSBtYXhlcykKCnByZWRfdW5pZiA8LSBwcmVkaWN0KGZpdF9sYW5kc2lua19lcnIsIG5ld2RhdGEgPSBYX3VuaWYsIHR5cGUgPSAnVUsnKQoKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMiwgd2FybmluZz1GQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQoKCnBhcihvbWEgPSBjKDAsMCwwLDMpLCBiZyA9ICd3aGl0ZScpCnBhaXJzKFhfbGV2ZWwxYSwKICAgICAgbGFiZWxzID0gMTpkLAogICAgICBnYXAgPSAwLCBsb3dlci5wYW5lbCA9IE5VTEwsIHhsaW0gPSBjKDAsMSksIHlsaW0gPSBjKDAsMSksCiAgICAgIHBhbmVsID0gY3BvaW50cywKICAgICAgej0gbGFuZHNpbmtfbW9kZXJuX2Vuc19sZXZlbDFhLAogICAgICBjb2wgPSBieXIsCiAgICAgIGNleC5sYWJlbHMgPSAxLAogICAgICBjb2wuYXhpcyA9ICd3aGl0ZScsCiAgICAgIHBjaCA9IDIwCiAgICAgICkKCiNpbWFnZS5wbG90KGxlZ2VuZC5vbmx5ID0gVFJVRSwKIyAgICAgICAgICAgemxpbSA9IGMoMCwxKSwKIyAgICAgICAgICAgY29sID0gYmx1ZXMsCiMgICAgICAgICAgIGxlZ2VuZC5hcmdzID0gbGlzdCh0ZXh0ID0gJ0RlbnNpdHkgb2YgbW9kZWwgcnVucyBtYXRjaGluZyB0aGUgY3JpdGVyaWEnLCBzaWRlID0gMywgbGluZSA9IDEpLAojICAgICAgICAgICBob3Jpem9udGFsID0gVFJVRQojKQoKIyAgbGVnZW5kKCdsZWZ0JywgbGVnZW5kID0gcGFzdGUoMTpkLCBjb2xuYW1lcyhsaHMpKSwgY2V4ID0gMC45LCBidHkgPSAnbicpCgoKYGBgCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTJ9CgoKWF9rZXB0IDwtIFhfdW5pZlthYnMocHJlZF91bmlmJG1lYW4pIDwgMSwgXSAKCnBhcihvbWEgPSBjKDAsMCwwLDMpLCBiZyA9ICd3aGl0ZScpCnBhaXJzKFhfa2VwdCwKICAgICAgbGFiZWxzID0gMTpkLAogICAgICBnYXAgPSAwLCBsb3dlci5wYW5lbCA9IE5VTEwsIHhsaW0gPSBjKDAsMSksIHlsaW0gPSBjKDAsMSksCiAgICAgIHBhbmVsID0gZGZ1bmNfdXAsCiAgICAgIGNleC5sYWJlbHMgPSAxLAogICAgICBjb2wuYXhpcyA9ICd3aGl0ZScsCiAgICAgIGRmdW5jLmNvbCA9IGJsdWVzKQoKaW1hZ2UucGxvdChsZWdlbmQub25seSA9IFRSVUUsCiAgICAgICAgICAgemxpbSA9IGMoMCwxKSwKICAgICAgICAgICBjb2wgPSBibHVlcywKICAgICAgICAgICBsZWdlbmQuYXJncyA9IGxpc3QodGV4dCA9ICdEZW5zaXR5IG9mIG1vZGVsIHJ1bnMgbWF0Y2hpbmcgdGhlIGNyaXRlcmlhJywgc2lkZSA9IDMsIGxpbmUgPSAxKSwKICAgICAgICAgICBob3Jpem9udGFsID0gVFJVRQopCgpsZWdlbmQoJ2xlZnQnLCBsZWdlbmQgPSBwYXN0ZSgxOmQsIGNvbG5hbWVzKGxocykpLCBjZXggPSAwLjksIGJ0eSA9ICduJykKCgoKCgpgYGAKCgojIyBBdWdtZW50IHRoZSBkZXNpZ24uClRoZSBmdW5jdGlvbiBhZGROcm95RGVzaWduUG9pbnRzIGJ1aWxkcyBhbiBlbXVsYXRvciBmb3IgZWFjaCBtb2RlbCBvdXRwdXQgaW4gWS4gSXQgY29tcGFyZXMgdGhlIG91dHB1dCBvZiBlYWNoIGVtdWxhdG9yIGF0IGEgbnVtYmVyIG9mIGNhbmRpZGF0ZSBkZXNpbiBwb2ludHMsIGFuZCBjaG9vc2VzIGEgc3BhY2UtZmlsbGluZyBzZXQgb2YgdGhlbSB0aGF0IHRoYXQgYXJlIE5vdCBSdWxlZCBPdXQgWWV0IChzdGF0aXN0aWNhbGx5IGNsb3NlIHRvIHRoZSBvYnNlcnZhdGlvbiBhdCBZX3RhcmdldCkuCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CiMgRmluYWwgb3V0cHV0IG5lZWRzIHRvIGJlIGV4cHJlc3NlZCBpbiB0ZXJtcyBvZiBvcmlnaW5hbCBMSFMsIHRoZW4gcHV0IGJhY2sgb3V0IHRvIGNvbmYgZmlsZXMuCgojIFRoaXMgZnVuY3Rpb24gYWRkcyBuLmF1ZyBwb3RlbnRpYWwgZGVzaWduIHBvaW50cywgYW5kIGZpbmRzIHRoZWlyIGltcGxhdXNpYmlsaXR5CiMgc2NvcmUgaW4gWC5ucm95Cgp3YXZlMSA9IGFkZE5yb3lEZXNpZ25Qb2ludHMoWCA9IFhfbGV2ZWwxYSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBZID0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBZX3RhcmdldCA9IFlfdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9hdWcgPSA1MDAwMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5zX2F1ZyA9IG1pbnNfYXVnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4ZXNfYXVnID0gbWF4ZXNfYXVnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyZXMgPSAzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY19saXN0PWRpc2NfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nfc2RfbGlzdCA9IGRpc2Nfc2RfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic19zZF9saXN0ID0gb2JzX3NkX2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2FwcCA9IDUwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5yZXBzID0gNTAwKQpgYGAKCgoKCiMjIFdyaXRlIHRoZSBhdWdtZW50ZWQgZGVzaWduClRoZSBmdW5jdGlvbiB3cml0ZV9qdWxlc19kZXNpZ24gaGVyZSBzaW1wbHkgdGFrZXMgdGhlIHBvaW50cyBjYWxjdWxhdGVkIGJ5IGFkZE5yb3lEZXNpZ25Qb2ludHMgYW5kIHdyaXRlcyB0aGVtIHRvIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgpgYGB7cn0KCiMgdGhpcyBuZWVkcyBzb3J0aW5nCnNvdXJjZSgnfi9teVJwYWNrYWdlcy9qdWxlc1IvdmlnbmV0dGVzL2RlZmF1bHRfanVsZXNfcGFyYW1ldGVyX3BlcnR1cmJhdGlvbnMuUicpCgojIEVhc2llc3Qgd2F5IHRvIGdlbmVyYXRlIGEgZGVzaWduIG9mIHRoZSByaWdodCBzaXplIGlzIHRvIGhhdmUgYSAiZmFjIiB3aGljaCB0YWtlcwojIHRoZSBuYW1lcyBmcm9tIHRoZSBwYXJhbWV0ZXIgbGlzdCwgYW5kIHRoZW4gbXVsdGlwbGllcyBldmVyeXRoaW5nIGJ5IDAuNSBvciAyCgp0ZiA8LSAnbF92Z19zb2lsJwojIHdlIGRvbid0IHdhbnQgYW55dGhpbmcgdGhhdCBpcyBUUlVFL0ZBTFNFIHRvIGJlIGluIGZhYwpmYWNfaW5pdCA8LSBuYW1lcyhwYXJhbWxpc3QpCm5vdF90Zl9peCA8LSB3aGljaChuYW1lcyhwYXJhbWxpc3QpIT10ZikKcGFyYW1saXN0X3RydW5jIDwtcGFyYW1saXN0W25vdF90Zl9peF0KCmZhYyA8LSBuYW1lcyhwYXJhbWxpc3RfdHJ1bmMpCgptYXhmYWMgPC1sYXBwbHkocGFyYW1saXN0X3RydW5jLGZ1bmN0aW9uKHgpIHgkbWF4W3doaWNoLm1heCh4JG1heCldIC8geCRzdGFuZGFyZFt3aGljaC5tYXgoeCRtYXgpXSkKbWluZmFjIDwtIGxhcHBseShwYXJhbWxpc3RfdHJ1bmMsZnVuY3Rpb24oeCkgeCRtaW5bd2hpY2gubWF4KHgkbWF4KV0gLyB4JHN0YW5kYXJkW3doaWNoLm1heCh4JG1heCldKQoKCmBgYAoKCmBgYHtyfQojIGNyZWF0ZSBhIGRpcmVjdG9yeSBmb3IgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMKY29uZmRpciA8LSAnY29uZl9maWxlc19hdWdtZW50X0pVTEVTLUVTLTFwMCcKCmRpci5jcmVhdGUoY29uZmRpcikKClhfbW0gPC0gd2F2ZTEkWF9tbQoKIyBUaGlzIGlzIHRoZSBmdW5jdGlvbiB0aGF0IHdyaXRlcyB0aGUgY29uZmlndXJhdGlvbiBmaWxlcy4Kd3JpdGVfanVsZXNfZGVzaWduKFhfbW0gPSBYX21tLCBwYXJhbWxpc3Q9cGFyYW1saXN0LCBuID0gbnJvdyhYX21tKSwKICAgICAgICAgICAgICAgICAgICBmYWMgPSBmYWMsIG1pbmZhYyA9IG1pbmZhYywgbWF4ZmFjID0gbWF4ZmFjLAogICAgICAgICAgICAgICAgICAgIHRmID0gdGYsCiAgICAgICAgICAgICAgICAgICAgZm5wcmVmaXggPSBwYXN0ZTAoY29uZmRpciwnL3BhcmFtLXBlcnR1cmItUCcpLAogICAgICAgICAgICAgICAgICAgIGxoc2ZuID0gcGFzdGUwKGNvbmZkaXIsJy9saHNfZXhhbXBsZS50eHQnKSwKICAgICAgICAgICAgICAgICAgICBzdGFuZm4gPSBwYXN0ZTAoY29uZmRpciwnL3N0YW5wYXJtc19leGFtcGxlLnR4dCcpLAogICAgICAgICAgICAgICAgICAgIGFsbHN0YW5mbiA9IHBhc3RlMChjb25mZGlyLCcvYWxsc3RhbnBhcm1zX2V4YW1wbGUudHh0JyksCiAgICAgICAgICAgICAgICAgICAgcm4gPSAxMiwKICAgICAgICAgICAgICAgICAgICBzdGFydG51bSA9IDUwMCkKYGBgCgojIyBDaGVjayB0aGUgZGVzaWduCkNoZWNrIHRoYXQgdGhlIGF1Z21lbnRlZCBkZXNpZ24gcHJvZHVjZXMgd2hhdCB3ZSBleHBlY3QuIE5ldyBlbnNlbWJsZSBtZW1iZXJzIHNob3VsZCBiZSBzb21ld2hhdCBjb25zdHJhaW5lZCB3aXRoaW4gdGhlIGJvdW5kYXJpZXMgb2YgdGhlIG9yaWdpbmFsIGRlc2lnbiwgaWYgdGhlIGNvbXBhcmlzb24gdG8gZGF0YSBvZmZlcnMgYW55IGNvbnN0cmFpbnQuCgpgYGB7ciwgZmlnLndpZHRoID0gMTUsIGZpZy5oZWlnaHQgPSAxNX0KCgpYX21tIDwtIHdhdmUxJFhfbW0KCnBhaXJzKHJiaW5kKFgsIFhfbW0pLCB4bGltID0gYygwLDEpLCB5bGltID0gYygwLDEpLCBnYXAgPSAwLCBsb3dlci5wYW5lbCA9IE5VTEwsIAogICAgICBjb2wgPSBjKHJlcCgnZ3JleScsIG5yb3coWCkpLCByZXAoJ3JlZCcsIG5yb3coWF9tbSkpKSwKICAgICAgcGNoID0gYyhyZXAoMjEsIG5yb3coWCkpLCByZXAoMjAsIG5yb3coWF9tbSkpKQogICAgICApCgpwYXIoeHBkID0gTkEpCgpsZWdlbmQoJ2JvdHRvbScsCiAgICAgICBsZWdlbmQgPSBjKCdPcmlnaW5hbCBkZXNpZ24nLCAnTmV3IHBvaW50cycpLAogICAgICAgY29sID0gYygnZ3JleScsICdyZWQnKSwKICAgICAgIGluc2V0ID0gMC4xNSwKICAgICAgIGNleCA9IDEuNSwKICAgICAgIHBjaCA9IGMoMjEsMjApCikKCmBgYAoKClZpc3VhbGlzZSB0aGUgcHJlZGljdGVkIG91dHB1dHMgYXQgdGhlIE5ST1kgcG9pbnRzIG9mIHRoZSBvbGQgZGVzaWduLCBhbmQgdGhlIG5ldyBzdWdnZXN0ZWQgZGVzaWduLgpgYGB7cn0KWV9tbV9saXN0IDwtIHZlY3Rvcihtb2RlID0nbGlzdCcsIGxlbmd0aCA9IGxlbmd0aCh3YXZlMSRmaXRfbGlzdCkpCgpmb3IoaSBpbiAxOmxlbmd0aCh3YXZlMSRmaXRfbGlzdCkpewoKeV9tbSA8LSBwcmVkaWN0KG9iamVjdD13YXZlMSRmaXRfbGlzdFtbaV1dLCBuZXdkYXRhID0gd2F2ZTEkWF9tbSwgdHlwZSA9ICdVSycpCgpZX21tX2xpc3RbW2ldXSA8LSB5X21tCgp9CmBgYAoKIyMgVmlzdWFsaXNpbmcgdGhlIGVtdWxhdGVkIG91dHB1dHMgYXQgdGhlIHByb3Bvc2VkIG5ldyBkZXNpZ24gcG9pbnRzLgoKSW50ZXJlc3RpbmdseSwgdGhlc2UgYXJlbid0IHBlcmZlY3RseSB3aXRoaW4gdGhlIG9yaWdpbmFsIGhhcmQgYm91bmRhcmllcyBzZXQgYnkgQW5keSwgZXZlbiB0aG91Z2ggSSd2ZSBzZXQgdGhvc2UgYm91bmRhcmllcyB0byBiZSB0aGUgKy0gNCBzdGFuZGFyZCBkZXZpYXRpb24gdGhyZWhvbGRzIGluIHRoZSBIaXN0b3J5IE1hdGNoLiBJIHN1Z2dlc3QgdGhpcyBpcyBiZWNhdXNlIHRoZXJlIGlzIG1vZGVsIGRpc2NyZXBhbmN5LCBhbmQgdGhhdCB0aGVyZSBpcyBjb25zaWRlcmFibGUgd3JpZ2dsZSByb29tIGluZHVjZWQgZnJvbSBlbXVsYXRvciB1bmNlcnRhaW50eS4KCkluIHBhcnRpY3VsYXIsIGl0IGFwcGVhcnMgdGhhdCB2ZWdldGF0aW9uIGNhcmJvbiBpcyBkaWZmaWN1bHQgdG8ga2VlcCBoaWdoLCBhbmQgdGhhdCBtYW55IE5ST1kgcHJvcG9zZWQgbWVtYmVycyBoYXZlIGEgZmFpcmx5IGxvdyB2ZWdldGF0aW9uIGNhcmJvbi4gVGhpcyBtaWdodCBuZWVkIGEgZGlzY3JlcGFuY3kgdGVybSwgb3IgYWRqdXN0aW5nIGluIHNvbWUgb3RoZXIgd2F5LiBJdCBjZXJ0YWlubHkgbmVlZHMgZXhwbG9yaW5nLCBhbmQgYSBPQUFUIHBsb3QgbWlnaHQgZ2l2ZSBjbHVlcyBhcyB0byB0aGUgcGFyYW1ldGVycyB0byBjaG9vc2UuCgpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0KIyBIaXN0b2dyYW0gb2YgbGV2ZWwgMSBjb25zdHJhaW50cwpoY29sID0gJ2RhcmtncmV5JwpsY29sID0gJ2JsYWNrJwpwYXIobWZyb3cgPSBjKDIsMiksIGZnID0gJ2RhcmtncmV5JywgbGFzID0gMSkKCmRpc2NzZCA8LSBjKGRpc2Nfc2RfbGlzdCwgcmVjdXJzaXZlID0gVFJVRSkKCmhpc3QoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25icF9sbmRfc3VtJ10sIGNvbCA9IGhjb2wsIG1haW4gPSAnTkJQJywgeGxhYiA9ICdHdEMveWVhcicpCmhpc3QoWV9tbV9saXN0W1sxXV0kbWVhbiwgYWRkID0gVFJVRSwgY29sID0gJ2JsYWNrJykKcG9seWdvbih4ID0gYygtMTAsIDEwMCwgMTAwLCAtMTApLCB5ID0gYygwLCAwLCAxMDAwLCAxMDAwKSwKICAgICAgICBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSwKICAgICAgICBib3JkZXIgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSkKcnVnKFlfdGFyZ2V0WzFdLCBjb2wgPSAnYmxhY2snKQpydWcoYyhZX3RhcmdldFsxXSArIDMqZGlzY3NkWzFdLFlfdGFyZ2V0WzFdIC0gMypkaXNjc2RbMV0pICwgY29sID0gJ3JlZCcpCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCducHBfbmxpbV9sbmRfc3VtJ10sIGNvbCA9IGhjb2wgLCBtYWluID0gJ05QUCcsIHhsYWIgPSAnR3RDL3llYXInKQpoaXN0KFlfbW1fbGlzdFtbMl1dJG1lYW4sIGFkZCA9IFRSVUUsIGNvbCA9ICdibGFjaycpCnBvbHlnb24oeCA9IGMoMzUsIDgwLCA4MCwgMzUpLCB5ID0gYygwLCAwLCAxMDAwLCAxMDAwKSwKICAgICAgICBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSwKICAgICAgICBib3JkZXIgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSkKcnVnKFlfdGFyZ2V0WzJdLCBjb2wgPSAnYmxhY2snKQpydWcoYyhZX3RhcmdldFsyXSArIDMqZGlzY3NkWzJdLFlfdGFyZ2V0WzJdIC0gMypkaXNjc2RbMl0pICwgY29sID0gJ3JlZCcpCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10sIGNvbCA9IGhjb2wsIG1haW4gPSAnU29pbCBDYXJib24nLCB4bGFiID0gJ0d0QycpCmhpc3QoWV9tbV9saXN0W1szXV0kbWVhbiwgYWRkID0gVFJVRSwgY29sID0gJ2JsYWNrJykKcG9seWdvbih4ID0gYyg3NTAsIDMwMDAsIDMwMDAsIDc1MCksIHkgPSBjKDAsIDAsIDEwMDAsIDEwMDApLAogICAgICAgIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpLAogICAgICAgIGJvcmRlciA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpKQpydWcoWV90YXJnZXRbM10sIGNvbCA9ICdibGFjaycpCnJ1ZyhjKFlfdGFyZ2V0WzNdICsgMypkaXNjc2RbM10sWV90YXJnZXRbM10gLSAzKmRpc2NzZFszXSkgLCBjb2wgPSAncmVkJykKCmhpc3QoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddLCBjb2wgPSBoY29sLCBtYWluID0gJ1ZlZ2V0YXRpb24gQ2FyYm9uJywgeGxhYiA9ICdHdEMnKQpoaXN0KFlfbW1fbGlzdFtbNF1dJG1lYW4sIGFkZCA9IFRSVUUsIGNvbCA9ICdibGFjaycpCnBvbHlnb24oeCA9IGMoMzAwLCA4MDAsIDgwMCwgMzAwKSwgeSA9IGMoMCwgMCwgMTAwMCwgMTAwMCksCiAgICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJyksCiAgICAgICBib3JkZXIgPSAgbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJykpCnJ1ZyhZX3RhcmdldFs0XSwgY29sID0gJ2JsYWNrJykKcnVnKGMoWV90YXJnZXRbNF0gKyAzKmRpc2NzZFs0XSxZX3RhcmdldFs0XSAtIDMqZGlzY3NkWzRdKSAsIGNvbCA9ICdyZWQnKQogIApgYGAKCgpIb3cgZ29vZCBhcmUgdGhlIGZvdXIgZW11bGF0b3JzIHRoYXQgd2UndmUgYnVpbHQ/IEFyZSB0aGVyZSBiaWFzZXM/ICh0aGVyZSdzIG5vIHJlYWwgZXZpZGVuY2Ugb2YgdGhpcykKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4fQoKcGFyKG1mcm93ID0gYygyLDIpKQoKZm9yKGkgaW4gMTo0KXsKICAKaGlzdCh3YXZlMSRwcmVkX2xpc3RbW2ldXSRtZWFuLCBtYWluID0gY29sbmFtZXMoWV9jb25zdF9sZXZlbDFhX3NjYWxlZClbaV0pCiAgCn0KCgpgYGAKCiMjIE9uZS1hdC1hLXRpbWUgc2Vuc2l0aXZpdHkgYW5hbHlzaXMgZm9yIHVuZGVyc3RhbmRpbmcgbW9kZWwgcmVzcG9uc2UKSXQncyBvYnZpb3VzbHkgaGFyZCB0byBtYWludGFpbiBhIGhpZ2ggdmVnZXRhdGlvbiBjYXJib24gaW4gcGFydGljdWxhci4gV2hhdCBwYXJhbWV0ZXIgdmFsdWVzIG1pZ2h0IHlvdSBjaG9vc2UgdG8gZG8gdGhpcywgYW5kIHdoYXQgbWlnaHQgYmUgdGhlIHRyYWRlLW9mZnMgeW91IGhhdmUgdG8gbWFrZT8KCgpgYGB7cn0KClhfb2FhdF9sZXZlbDFhIDwtIG9hYXRfZGVzaWduKFhfbGV2ZWwxYSwgbj0yMSwgbWVkID0gVFJVRSkKY29sbmFtZXMoWF9vYWF0X2xldmVsMWEpID0gY29sbmFtZXMoWCkKCnlfb2FhdCA8LSBwcmVkaWN0LmttKHdhdmUxJGZpdF9saXN0W1s0XV0sIG5ld2RhdGEgPSBYX29hYXRfbGV2ZWwxYSwgdHlwZSA9ICdVSycpCgpgYGAKCgoKCkZpcnN0LCB3aGF0IHBhcmFtZXRlcnMgYWZmZWN0IHZlZ2V0YXRpb24gY2FyYm9uIGFuZCBob3c/IEhvdyBzdXJlIGFyZSB3ZSBhYm91dCB0aGF0PwoKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSAxMH0KCgpvYWF0TGluZVBsb3QoWF9vYWF0ID0gWF9vYWF0X2xldmVsMWEsIHlfb2FhdF9tZWFuID0geV9vYWF0JG1lYW4sIHlfb2FhdF9zZCA9IHlfb2FhdCRzZCwgCiAgICAgICAgICAgICBuX29hYXQgPSAyMSxuciA9IDYsIG5jID0gNikgCgoKYGBgCgoKCmBgYHtyfQoKWV9vYWF0X2NvbnN0X2xldmVsMWFfc2NhbGVkIDwtIG1hdHJpeChuY29sID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSwgbnJvdyA9IG5yb3coWF9vYWF0X2xldmVsMWEpKQoKZm9yKGkgaW4gMTpuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKXsKCiAgeV9vYWF0IDwtIHByZWRpY3Qua20od2F2ZTEkZml0X2xpc3RbW2ldXSwgbmV3ZGF0YSA9IFhfb2FhdF9sZXZlbDFhLCB0eXBlID0gJ1VLJykKICBZX29hYXRfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLGldIDwtIHlfb2FhdCRtZWFuCn0KCmBgYAoKCldoYXQgbWlnaHQgYmUgdGhlIHRyYWRlLW9mZnMgZm9yIGEgaGlnaCAob3IgYWNjdXJhdGUpIHZlZ2V0YXRpb24gY2FyYm9uPyBhcmUgdGhleSBhY2NlcHRhYmxlPyBQbG90IHRoZSBvYWF0IHNlbnNpdGl2aXR5IG9mIHRoZSBvdGhlciAzIG91dHB1dHMgd2UncmUgY2FsaWJyYXRpbmcgb24uIAoKYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodCA9IDEwfQpZX29hYXRfY29uc3RfbGV2ZWwxYV9zY2FsZWRfbm9ybSA8LSBub3JtYWxpemUoWV9vYWF0X2NvbnN0X2xldmVsMWFfc2NhbGVkKQoKb2FhdExpbmVQbG90TXVsdGkoWF9vYWF0ID0gWF9vYWF0X2xldmVsMWEsIFlfb2FhdCA9IFlfb2FhdF9jb25zdF9sZXZlbDFhX3NjYWxlZF9ub3JtICwgIG5fb2FhdCA9IDIxLCBuciA9IDYsIG5jID0gNiwKICAgICAgICAgICAgICAgICAgbHdkID0gMikKCnJlc2V0KCkKbGVnZW5kKCd0b3AnLCBjKCduYnAnLCAnbnBwJywgJ2Nzb2lsJywgJ2N2ZWcnKSwgY29sID0gYygxLDIsMyw0KSwgbHR5ID0gJ3NvbGlkJywgbHdkID0gMiwgaG9yaXogPSBUUlVFKQoKCmBgYAoKCldoYXQgZG8gdGhlIGVtdWxhdG9ycyBtYWtlIG9mIHRoZSBkZXNpZ24gcG9pbnRzIHdoaWNoIGFjdHVhbGx5IG1ha2UgQW5keSdzICJoYXJkIGJvdW5kYXJ5IiBjcml0ZXJpYT8KSWYgd2UgbGVhdmUgdGhlbSBvdXQsIGRvIHRoZXkgc3RpbGwgcGxhY2UgdGhlIG91dHB1dCB3aXRoaW4gdGhlIGhhcmQgYm91bmRhcmllcz8KCmBgYHtyfQoKYXdfYm91bmRhcnlfaXggPSB3aGljaChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbmJwX2xuZF9zdW0nXSA+IC0xMCAmCiAgICAgICAgICAgICAgICAgICAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25wcF9ubGltX2xuZF9zdW0nXSA+IDM1ICYgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCducHBfbmxpbV9sbmRfc3VtJ10gPCA4MCAmCiAgICAgICAgICAgICAgICAgICAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NTb2lsX2xuZF9zdW0nXSA+IDc1MCAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10gPCAzMDAwICYKICAgICAgICAgICAgICAgICAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddID4gMzAwICYgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddIDwgODAwCiAgKQoKCgpYX2F3X2JvdW5kYXJ5ID0gWF9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LCBdCllfYXdfYm91bmRhcnkgPSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBdCgpgYGAKCiMjIENoZWNrIHRoZSBlbXVsYXRvcnMgdGhhdCBwcm9kdWNlIHRoZSBuZXcgZGVzaWduCkRvIGEgbGVhdmUtb25lLW91dCBjcm9zcyB2YWxpZGF0aW9uIG9mIHBvaW50cyBpbnNpZGUgdGhlIGhhcmQgYm91bmRhcmllcyB1c2luZyB0aGUgd2F2ZTEgZml0cy4KYGBge3J9CiMgcXVpY2tlc3QgdG8gZmluZCB0aGUgbG9vIHByZWRpY3Rpb25zIGF0IHRoZSByaWdodCBpbmRpY2VzCgoKYGBgCgpgYGB7cn0KCmxvb19tZWFuX1lfbGV2ZWwxYSA8LSBtYXRyaXgobnJvdyA9IG5yb3coWF9sZXZlbDFhKSwgbmNvbCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpCmxvb19zZF9ZX2xldmVsMWEgPC0gbWF0cml4KG5yb3cgPSBucm93KFhfbGV2ZWwxYSksIG5jb2wgPSBuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKQogIAogIGZvcihpIGluIDE6bmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSl7Cgpsb28gPC0gbGVhdmVPbmVPdXQua20od2F2ZTEkZml0X2xpc3RbW2ldXSx0eXBlID0gJ1VLJywgdHJlbmQucmVlc3RpbSA9IFRSVUUgKQogIGxvb19tZWFuX1lfbGV2ZWwxYVssaV0gPC0gbG9vJG1lYW4KICBsb29fc2RfWV9sZXZlbDFhWyxpXSA8LSBsb28kc2QKfQoKYGBgCgpXZSBzZWUgaW4gdGhlIGxlYXZlLW9uZS1vdXQgYW5hbHlzaXMgdGhhdCB0aGUgZW11bGF0b3IgaXMgY29uc2lzdGVudGx5IHVuZGVyLXByZWRpY3RpbmcgdGhlIHZlZ2V0YXRpb24gY2FyYm9uICh0aG91Z2ggdGhlIHVuY2VydGFpbnR5IGVzdGltYXRlIG9mdGVuIGNvdmVycyB0aGUgYWN0dWFsIHZhbHVlKS5UaGlzIHN1Z2dlc3RzICgxKSB0aGF0IHRoZXJlIGlzbid0IHJlYWxseSBhIGh1Z2UgcHJvYmxlbSB3aXRoIGEgbW9kZWwgZGlzY3JlcGFuY3kgKG9yIGF0IGxlYXN0IHRoYXQgaXNuJ3QgdGhlIG9ubHkgcHJvYmxlbSksIGFuZCAoMikgdGhlIGhpc3RvcnkgbWF0Y2hpbmcgaXMgd29ya2luZyBhcyBpdCBzaG91bGQsIGFuZCB0YWtpbmcgaW50byBhY2NvdW50IGEgbm90LWdyZWF0IGVtdWxhdG9yLgoKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4fQoKcGFyKG1mcm93ID0gYygyLDIpKQoKZm9yKGkgaW4gMTpuY29sKGxvb19tZWFuX1lfbGV2ZWwxYSkpewogIAogIHJuIDwtIHJhbmdlKGMobG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldIC0gKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgLCBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gKyAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSApKQogIAogIAogIAogIHBsb3QoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSwgeWxpbSA9IHJuLCBtYWluID0gY29sbmFtZXMoWV9jb25zdF9sZXZlbDFhX3NjYWxlZClbaV0sIHhsYWIgPSAnYWN0dWFsJywgeWxhYiA9ICdwcmVkaWN0ZWQnKQogIAogIHNlZ21lbnRzKHgwID0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIHkwID0gbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldIC0gKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgICwgeDEgPSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSAsIHkxID0gbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldICsgKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApKQogIGFibGluZSgwLDEpCiAgCn0KCgpgYGAKCiMjIENvbXBhcmUgdGhlIHN0cmFpZ2h0IGttIHdpdGggYSB0d28tc3RlcCBlbXVsYXRvcgpJcyBhIHR3by1zdGVwIGVtdWxhdG9yIGFueSBiZXR0ZXIgYXQgZW11bGF0aW5nIHRob3NlIGNydWNpYWwgcG9pbnRzIHdoaWNoIGZhbGwgd2l0aGluIGF3J3MgaGFyZCBib3VuZGFyaWVzPyBGaXJzdCwgY3JlYXRlIGEgbGlzdCBvZiBlbXVsYXRvciBmaXRzLgoKYGBge3J9CgpmaXRsaXN0X1lfY29uc3RfbGV2ZWwxYV9zY2FsZWQgPC0gdmVjdG9yKG1vZGUgPSAnbGlzdCcsIGxlbmd0aCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpCgpmb3IoaSBpbiAxOm5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpewogIAogIHkgPC0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssaV0KICBmaXQgPC0gdHdvU3RlcF9nbG1uZXQoWCA9IFhfbGV2ZWwxYSwgeSkKICBmaXRsaXN0X1lfY29uc3RfbGV2ZWwxYV9zY2FsZWRbW2ldXSA8LSBmaXQKCn0KCgpgYGAKCmBgYHtyfQpsb29fbWVhbl9nbG1uZXRfWV9sZXZlbDFhIDwtIG1hdHJpeChucm93ID0gbnJvdyhYX2xldmVsMWEpLCBuY29sID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSkKbG9vX3NkX2dsbW5ldF9ZX2xldmVsMWEgPC0gbWF0cml4KG5yb3cgPSBucm93KFhfbGV2ZWwxYSksIG5jb2wgPSBuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKQogIAogIGZvcihpIGluIDE6bmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSl7Cgpsb28gPC0gbGVhdmVPbmVPdXQua20oZml0bGlzdF9ZX2NvbnN0X2xldmVsMWFfc2NhbGVkW1tpXV0kZW11bGF0b3IsdHlwZSA9ICdVSycsIHRyZW5kLnJlZXN0aW0gPSBUUlVFICkKICBsb29fbWVhbl9nbG1uZXRfWV9sZXZlbDFhWyxpXSA8LSBsb28kbWVhbgogIGxvb19zZF9nbG1uZXRfWV9sZXZlbDFhWyxpXSA8LSBsb28kc2QKfQoKYGBgCgpJdCBkb2Vzbid0IGFwcGVhciB0aGF0IHRoZSB0d28tc3RlcCBlbXVsYXRvciAoaGVyZSBwbG90dGVkIGluIHJlZCkgaXMgZG9pbmcgYW55IGJldHRlciB0aGFuIHRoZSByZWd1bGFyIGVtdWxhdG9yLgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDh9CnBhcihtZnJvdyA9IGMoMiwyKSkKCmZvcihpIGluIDE6bmNvbChsb29fbWVhbl9ZX2xldmVsMWEpKXsKICAKICBybiA8LSByYW5nZShjKGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSAtICgyKmxvb19zZF9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0pICwgbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldICsgKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgKSkKICAKICAKICAKICBwbG90KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIGldLCBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0sIHlsaW0gPSBybiwgbWFpbiA9IGNvbG5hbWVzKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpW2ldLCB4bGFiID0gJ2FjdHVhbCcsIHlsYWIgPSAncHJlZGljdGVkJykKICAKICBwb2ludHMoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIGxvb19tZWFuX2dsbW5ldF9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0sIGNvbCA9ICdyZWQnKQogIAogIAogIHNlZ21lbnRzKHgwID0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIHkwID0gbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldIC0gKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgICwgeDEgPSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSAsIHkxID0gbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldICsgKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApKQogIGFibGluZSgwLDEpCiAgCn0KYGBgCgpUd28gb3RoZXIgdGhpbmdzIEkgY2FuIHRoaW5rIG9mIHRvIGNoZWNrOiAxKSBob3cgYWJvdXQgdXNpbmcgIm11bHRpc3RhcnQiIHRvIGNob29zZSBkaWZmZXJlbnQgc3RhcnRpbmcgY29uZGl0aW9ucyBmb3Igb3B0aW1pc2luZyB0aGUgZW11bGF0b3JzIGFuZCAyKSBVc2luZyBhIGZsYXQgcHJpb3IgZm9yIHRoZSBtZWFuIGZ1bmN0aW9uIHJhdGhlciB0aGFuIGEgbGluZWFyIHByaW9yLgpgYGB7cn0KCmZpdGxpc3RfZmxhdHByaW9yX1lfY29uc3RfbGV2ZWwxYV9zY2FsZWQgPC0gdmVjdG9yKG1vZGUgPSAnbGlzdCcsIGxlbmd0aCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpCgpmb3IoaSBpbiAxOm5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpewogIAogIHkgPC0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssaV0KICBmaXQgPC0ga20oZm9ybXVsYSA9fjEsIGRlc2lnbiA9IFhfbGV2ZWwxYSwgcmVzcG9uc2UgPSB5KQogIGZpdGxpc3RfZmxhdHByaW9yX1lfY29uc3RfbGV2ZWwxYV9zY2FsZWRbW2ldXSA8LSBmaXQKCn0KCgpgYGAKCmBgYHtyfQpsb29fbWVhbl9mbGF0cHJpb3JfWV9sZXZlbDFhIDwtIG1hdHJpeChucm93ID0gbnJvdyhYX2xldmVsMWEpLCBuY29sID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSkKbG9vX3NkX2ZsYXRwcmlvcl9ZX2xldmVsMWEgPC0gbWF0cml4KG5yb3cgPSBucm93KFhfbGV2ZWwxYSksIG5jb2wgPSBuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKQogIAogIGZvcihpIGluIDE6bmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSl7Cgpsb28gPC0gbGVhdmVPbmVPdXQua20oZml0bGlzdF9mbGF0cHJpb3JfWV9jb25zdF9sZXZlbDFhX3NjYWxlZFtbaV1dLHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSApCiAgbG9vX21lYW5fZmxhdHByaW9yX1lfbGV2ZWwxYVssaV0gPC0gbG9vJG1lYW4KICBsb29fc2RfZmxhdHByaW9yX1lfbGV2ZWwxYVssaV0gPC0gbG9vJHNkCn0KCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4fQpwYXIobWZyb3cgPSBjKDIsMikpCgpmb3IoaSBpbiAxOm5jb2wobG9vX21lYW5fWV9sZXZlbDFhKSl7CiAgCiAgcm4gPC0gcmFuZ2UoYyhsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gLSAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAsIGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSArICgyKmxvb19zZF9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0pICkpCiAgCiAgCiAgCiAgcGxvdChZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSwgbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldLCB5bGltID0gcm4sIG1haW4gPSBjb2xuYW1lcyhZX2NvbnN0X2xldmVsMWFfc2NhbGVkKVtpXSwgeGxhYiA9ICdhY3R1YWwnLCB5bGFiID0gJ3ByZWRpY3RlZCcpCiAgCiAgcG9pbnRzKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIGldLCBsb29fbWVhbl9mbGF0cHJpb3JfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldLCBjb2wgPSAncmVkJykKICAKICAKICBzZWdtZW50cyh4MCA9IFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIGldLCB5MCA9IGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSAtICgyKmxvb19zZF9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0pICAsIHgxID0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0gLCB5MSA9IGxvb19tZWFuX2ZsYXRwcmlvcl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gKyAoMipsb29fc2RfZmxhdHByaW9yX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApKQogIGFibGluZSgwLDEpCiAgCn0KCgoKYGBgCgoKCiMgRXhwbG9yaW5nIG5ldyBjb25zdHJhaW50cwpJbnB1dCBmcm9tIEVkZHkgUm9iZXJ0c29uOgoKIldlIGNhbiBhc3N1bWUgdGhhdCB0aGUgbWFqb3JpdHkgb2YgdmVnZXRhdGlvbiBjYXJib24gaXMgc3RvcmVkIGluIHRyZWUgdHJ1bmtzIHNvLCB0aGUgY2FyYm9uIGRlbnNpdHkgb2YgdHJlZXMgaXMgYXBwcm94aW1hdGVseSAoY1ZlZ19sbmRfbWVhbiAvIHRyZWVGcmFjX2xuZF9tZWFuKS4gQWx0aG91Z2ggSSBzdXBwb3NlIGl0J3MgcG9zc2libGUgdGhhdCBpbiB0aGUgUFBFIHRoZSBzaHJ1YnMgaGF2ZSBiZWNvbWUgdHJlZS1saWtlLCBzbyBpdCBtaWdodCBiZSBpbnRlcmVzdGluZyB0byBwbG90IGNWZWdfbG5kX21lYW4gdmVyc3VzICAoc2hydWJGcmFjX2xuZF9tZWFuICsgdHJlZUZyYWNfbG5kX21lYW4pIGFzIHdlbGwuIFRoZSBmaXJzdCBxdWVzdGlvbiBpcyB3aGV0aGVyIGNWZWdfbG5kX21lYW4gaW5jcmVhc2VzIGxpbmVhcmx5IHdpdGggdHJlZUZyYWNfbG5kX21lYW4uIFRoZW4gaWYgdGhpcyB0dXJuZWQgb3V0IHRvIGJlIGludGVyZXN0aW5nLCB3ZSBjb3VsZCBwcm9kdWNlIGEgdHJlZUNWZWdfbG5kX21lYW4gb3V0cHV0LiIKCmBgYHtyLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gN30KCiNwZGYoZmlsZSA9ICd2ZWdDX2RlbnNpdHkucGRmJywgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQpwbG90KFlfbGV2ZWwwWywndHJlZUZyYWNfbG5kX21lYW4nXSxZX2xldmVsMFssJ2NWZWdfbG5kX21lYW4nXSwgbWFpbiA9ICJWZWdldGF0aW9uICh0cmVlKSBjYXJib24gZGVuc2l0eSwgTGV2ZWwwIiwKICAgICB4bGFiID0gJ3RyZWVGcmFjX2xuZF9tZWFuJywgeWxhYiAgPSAnY1ZlZ19sbmRfbWVhbicgKQoKI2Rldi5vZmYoKQoKYGBgCgpJcyB0aGUgcmFuZ2Ugb2YgY2FyYm9uIGRlbnNpdGllcyBuYXJyb3dlciBpbiB0aGUgImhhcmQgYm91bmRhcnkiIHNldD8KYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA2fQoKWV9sZXZlbDFhX2F3IDwtIFlfbGV2ZWwxYVthd19ib3VuZGFyeV9peCwgXQpYX2xldmVsMWFfYXcgPC0gWF9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LCBdCgojcGRmKGZpbGUgPSAndmVnQ19kZW5zaXR5X2F3LnBkZicsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNikKcGxvdChZX2xldmVsMWFbLCd0cmVlRnJhY19sbmRfbWVhbiddLFlfbGV2ZWwxYVssJ2NWZWdfbG5kX21lYW4nXSwgbWFpbiA9ICJWZWdldGF0aW9uICh0cmVlKSBjYXJib24gZGVuc2l0eSIsCiAgICAgeGxhYiA9ICd0cmVlRnJhY19sbmRfbWVhbicsIHlsYWIgID0gJ2NWZWdfbG5kX21lYW4nICkKCnBvaW50cyggWV9sZXZlbDFhX2F3WywndHJlZUZyYWNfbG5kX21lYW4nXSxZX2xldmVsMWFfYXdbLCdjVmVnX2xuZF9tZWFuJ10sIHBjaCA9IDE5LCBjb2wgPSAncmVkJykKbGVnZW5kKCd0b3BsZWZ0JywgbGVnZW5kID0gYygnTGV2ZWwxYScsJ0FXIGNvbnN0cmFpbnRzJyksIHBjaCA9IGMoMjEsIDE5KSwgY29sID0gYygnYmxhY2snLCAncmVkJykpCiMgICBkZXYub2ZmKCkKCgoKYGBgCgoKCgpgYGB7cn0KY19kZW5zaXR5IDwtIFlfbGV2ZWwxYVssJ3RyZWVGcmFjX2xuZF9tZWFuJ10gLyBZX2xldmVsMWFbLCdjVmVnX2xuZF9tZWFuJ10KCmhpc3QoY19kZW5zaXR5KQoKCgpgYGAKCiMjIE5vdyB0aGF0IHdlIGhhdmUgY29uc3RyYWludHMsIHdlIGNhbiBleHBsb3JlIHRoZWlyIGVmZmVjdCBvbiB0aGUgb3V0cHV0IAoKYGBge3IsIGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gMjB9CiMgUGFpcnMgcGxvdCBvZiBvdXRwdXQKeV9uYW1lc19tZWFuIDwtIGMoJ25icF9sbmRfbWVhbicsICdmTHVjX2xuZF9tZWFuJywgJ25wcF9ubGltX2xuZF9tZWFuJywgJ2NTb2lsX2xuZF9tZWFuJywKICAgICAgICAgICAgJ2NWZWdfbG5kX21lYW4nLCAnbGFuZENvdmVyRnJhY19sbmRfbWVhbicsICdmSGFydmVzdF9sbmRfbWVhbicsCiAgICAgICAgICAgICdsYWlfbG5kX21lYW4nLCAncmhfbG5kX21lYW4nLCAndHJlZUZyYWNfbG5kX21lYW4nLCAnYzNQZnRGcmFjX2xuZF9tZWFuJywgCiAgICAgICAgICAgICdjNFBmdEZyYWNfbG5kX21lYW4nLCAnc2hydWJGcmFjX2xuZF9tZWFuJywgJ2JhcmVzb2lsRnJhY19sbmRfbWVhbicpCgpZX2xldmVsMWFfbWVhbiA8LSBZX2xldmVsMWFbLHlfbmFtZXNfbWVhbl0KCnBjb2wgPC0gcmVwKCdibGFjaycsIG5yb3coWV9sZXZlbDFhX21lYW4pKQpwY29sW2F3X2JvdW5kYXJ5X2l4XSA8LSAncmVkJwpwYWlycyhZX2xldmVsMWFfbWVhbiwgY29sID0gcGNvbCwgbG93ZXIucGFuZWwgPSBOVUxMLCBwY2ggPSAxOSwgY2V4LmxhYmVscyA9IDEuNSkKCgoKCmBgYAoKIyMgSG93IG11Y2ggZG9lcyBjb25zdHJhaW5pbmcgYW4gb3V0cHV0IGNvbnN0cmFpbiBvdGhlciBvdXRwdXRzPwpGb3IgZXhhbXBsZSwgd2hhdCBlZmZlY3QgaGFzIHRoZSBBVyAiaGFyZCBib3VuZGFyeSIgY29uc3RyYWludCBwcm9kdWNlZCBvbiByYW5nZXMgb2YgdGhlIG90aGVyIChtYXJnaW5hbCkgb3V0cHV0cz8gV2hpY2ggY29uc3RyYWludCBpcyBkb2luZyB0aGUgbWFqb3JpdHkgb2YgdGhlIHdvcms/CgoKQSBmdW5jdGlvbiB0byBmaW5kIHRoZSBwcm9wb3J0aW9uIG9mIG91dHB1dCBzcGFjZSB0aGF0IGlzIHJlbW92ZWQgKG9yIHJldGFpbmVkKSB3aGVuIGFwcGx5aW5nIGEgY29uc3RyYWludC4KYGBge3J9Cgpjb25zdHJhaW50X3Byb3AgPC0gZnVuY3Rpb24oWSwgY29uc3RyYWludF9peCl7CiAgCiAgWWNvbnN0IDwtIFlbY29uc3RyYWludF9peCwgXQogIFljb25zdF9ub3JtIDwtIG5vcm1hbGl6ZShZY29uc3QsIHdydCA9IFkpCiAgcm4gPC0gYXBwbHkoWWNvbnN0X25vcm0sIDIsIHJhbmdlKQogIG91dCA8LSBybgogIG91dAogIAp9CgoKYGBgCgpgYGB7cn0KWV9jb25zdHJhaW50X3Bsb3QgPC0gZnVuY3Rpb24oY29uc3RyYWludF9yYW5nZSwgY29uc3RyYWludF9jb2x1bW5zLCAuLi4pewogICMgQSBmdW5jdGlvbiB0byBwbG90IHRoZSBvdXRwdXQgb2YgY29uc3RyYWludF9wcm9wCiAgCiAgcGFyKG1hciA9IGMoMTIsNCwzLDIpLGxhcyA9IDIpCgpwY29sID0gcmVwKCdibGFjaycsIG5jb2woY29uc3RyYWludF9yYW5nZSkpCnBjb2xbY29uc3RyYWludF9jb2x1bW5zXSA8LSAncmVkJyAjIHBsb3QgdGhlIG91dHB1dHMgd2hlcmUgd2UgaGF2ZSBzcGVjaWZpZWQgdGhlIGNvbnN0cmFpbnRzIGluIHJlZC4KCnBsb3QoMTpuY29sKGNvbnN0cmFpbnRfcmFuZ2UpLGNvbnN0cmFpbnRfcmFuZ2VbMixdLCB5bGltID0gYygwLDEpICwgYXhlcyA9IEZBTFNFLCB4bGFiID0gJycsIHlsYWIgPSAncmFuZ2Ugb2YgZW5zZW1ibGUgKGZyYWN0aW9uKScsIGNvbCA9IHBjb2wsIHBjaCA9IDE5LCAuLi4pCnBvaW50cygxOm5jb2woY29uc3RyYWludF9yYW5nZSksIGNvbnN0cmFpbnRfcmFuZ2VbMSxdLCBjb2wgPSBwY29sLCBwY2ggPSAxOSkKc2VnbWVudHMoeDAgPSAxOm5jb2woY29uc3RyYWludF9yYW5nZSksIHkwID0gY29uc3RyYWludF9yYW5nZVsxLF0sIHgxID0gMTpuY29sKGNvbnN0cmFpbnRfcmFuZ2UpLCB5MSA9IGNvbnN0cmFpbnRfcmFuZ2VbMixdLCBjb2wgPSBwY29sLCBsd2QgPTIgKQoKYXhpcyhzaWRlID0gMSwgbGFiZWxzID0gY29sbmFtZXMoY29uc3RyYWludF9yYW5nZSksIGF0ID0gMTpuY29sKGNvbnN0cmFpbnRfcmFuZ2UpKQpheGlzKDIpCmFibGluZShoID0gYygwLDEpLCBjb2wgPSAncmVkJykKICAKfQpgYGAKCkFsbCBjb25zdHJhaW50cyB0b2dldGhlciB0YWtlIHRoZSBub3JtYWxpemVkIHJhbmdlIG9mIGFsbCB0aGUgb3V0cHV0cyB0byBhIGxpdHRsZSB1bmRlciBhIGhhbGYgb2YgdGhlIG9yaWdpbmFsIHJhbmdlLCBvbiBhdmVyYWdlLiBPZiBjb3Vyc2UsIGZvdXIgb2YgdGhlIGlucHV0cyBhcmUgY29uc3RyYWluZWQgaGVyZSwgd2hpY2ggaGFzIHF1aXRlIGEgbGFyZ2UgaW1wYWN0LgpgYGB7cn0KWV9sZXZlbDFhX21lYW5fYXdfbm9ybV9ybiA8LSBjb25zdHJhaW50X3Byb3AoWSA9IFlfbGV2ZWwxYV9tZWFuLCBjb25zdHJhaW50X2l4ID0gYXdfYm91bmRhcnlfaXgpCm1lYW5fY29uc3RyYWludF9hbGwgPC0gbWVhbihZX2xldmVsMWFfbWVhbl9hd19ub3JtX3JuWzIsIF0gLSBZX2xldmVsMWFfbWVhbl9hd19ub3JtX3JuWzEsIF0pCllfY29uc3RyYWludF9wbG90KFlfbGV2ZWwxYV9tZWFuX2F3X25vcm1fcm4sY29uc3RyYWludF9jb2x1bW5zID0gYyhjKDEsMyw0LDUpKSwgbWFpbiA9IHBhc3RlKCdtZWFuIGNvbnN0cmFpbmVkIHJhbmdlID0nLCByb3VuZChtZWFuX2NvbnN0cmFpbnRfYWxsLDMpKSkKYGBgCgpXZSBjYW4gc2VlIHdoYXQgaW1wYWN0cyB0aGUgY29uc3RyYWludHMgaGF2ZSBpbmRpdmlkdWFsbHkKYGBge3J9CgpuYnBfaXggPC0gd2hpY2goWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25icF9sbmRfc3VtJ10gPiAtMTApCm5wcF9peCA8LSB3aGljaChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddID4gMzUgJiAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25wcF9ubGltX2xuZF9zdW0nXSA8IDgwICkKY1NvaWxfaXggPC0gd2hpY2goWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NTb2lsX2xuZF9zdW0nXSA+IDc1MCAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10gPCAzMDAwKQpjVmVnX2l4IDwtIHdoaWNoKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSA+IDMwMCAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSA8IDgwMCkKCmBgYAoKVGhlIE5CUCBjb25zdHJhaW50IGhhcyBubyBtYXJnaW5hbCBpbXBhY3QKYGBge3J9CgpZX2xldmVsMWFfbWVhbl9uYnBfY29uc3QgPC0gY29uc3RyYWludF9wcm9wKFkgPSBZX2xldmVsMWFfbWVhbiwgY29uc3RyYWludF9peCA9IG5icF9peCApCm1lYW5fY29uc3RyYWludF9uYnAgPC0gbWVhbihZX2xldmVsMWFfbWVhbl9uYnBfY29uc3RbMiwgXSAtIFlfbGV2ZWwxYV9tZWFuX25icF9jb25zdFsxLCBdKQpZX2NvbnN0cmFpbnRfcGxvdChZX2xldmVsMWFfbWVhbl9uYnBfY29uc3QsMSwgIG1haW4gPSBwYXN0ZSgnbWVhbiBjb25zdHJhaW5lZCByYW5nZSA9Jywgcm91bmQobWVhbl9jb25zdHJhaW50X25icCwzKSkpCgpgYGAKCmBgYHtyfQoKWV9sZXZlbDFhX21lYW5fbnBwX2NvbnN0IDwtIGNvbnN0cmFpbnRfcHJvcChZID0gWV9sZXZlbDFhX21lYW4sIGNvbnN0cmFpbnRfaXggPSBucHBfaXggKQptZWFuX2NvbnN0cmFpbnRfbnBwIDwtIG1lYW4oWV9sZXZlbDFhX21lYW5fbnBwX2NvbnN0WzIsIF0gLSBZX2xldmVsMWFfbWVhbl9ucHBfY29uc3RbMSwgXSkKWV9jb25zdHJhaW50X3Bsb3QoWV9sZXZlbDFhX21lYW5fbnBwX2NvbnN0LDMsICBtYWluID0gcGFzdGUoJ21lYW4gY29uc3RyYWluZWQgcmFuZ2UgPScsIHJvdW5kKG1lYW5fY29uc3RyYWludF9ucHAsMykpKQoKYGBgCgoKYGBge3J9CgpZX2xldmVsMWFfbWVhbl9jU29pbF9jb25zdCA8LSBjb25zdHJhaW50X3Byb3AoWSA9IFlfbGV2ZWwxYV9tZWFuLCBjb25zdHJhaW50X2l4ID0gY1NvaWxfaXggKQptZWFuX2NvbnN0cmFpbnRfY1NvaWwgPC0gbWVhbihZX2xldmVsMWFfbWVhbl9jU29pbF9jb25zdFsyLCBdIC0gWV9sZXZlbDFhX21lYW5fY1NvaWxfY29uc3RbMSwgXSkKWV9jb25zdHJhaW50X3Bsb3QoWV9sZXZlbDFhX21lYW5fY1NvaWxfY29uc3QsNCwgIG1haW4gPSBwYXN0ZSgnbWVhbiBjb25zdHJhaW5lZCByYW5nZSA9Jywgcm91bmQobWVhbl9jb25zdHJhaW50X2NTb2lsLDMpKSkKCmBgYApWZWdldGF0aW9uIGNhcmJvbiAoY1ZlZykgaGFzIHRoZSBzdHJvbmdlc3QgaW1wYWN0IG9uIGV2ZXJ5dGhpbmcgZWxzZS4gVGhpcyBpcyBubyBzdXByaXNlLCBnaXZlbiB0aGF0IHNvIGZldyBvZiB0aGUgZW5zZW1ibGUgbWVtYmVycyBzZWVtIHRvIHNpbXVsYXRlIGNhcmJvbiB2ZWdldGF0aW9uIGhpZ2ggZW5vdWdoLgpgYGB7cn0KCllfbGV2ZWwxYV9tZWFuX2NWZWdfY29uc3QgPC0gY29uc3RyYWludF9wcm9wKFkgPSBZX2xldmVsMWFfbWVhbiwgY29uc3RyYWludF9peCA9IGNWZWdfaXggKQptZWFuX2NvbnN0cmFpbnRfY1ZlZyA8LSBtZWFuKFlfbGV2ZWwxYV9tZWFuX2NWZWdfY29uc3RbMiwgXSAtIFlfbGV2ZWwxYV9tZWFuX2NWZWdfY29uc3RbMSwgXSkKWV9jb25zdHJhaW50X3Bsb3QoWV9sZXZlbDFhX21lYW5fY1ZlZ19jb25zdCw1LCAgbWFpbiA9IHBhc3RlKCdtZWFuIGNvbnN0cmFpbmVkIHJhbmdlID0nLCByb3VuZChtZWFuX2NvbnN0cmFpbnRfY1ZlZywzKSkpCgpgYGAKCmBgYHtyfQoKIyB3aXRoIDMgcHJvY2Vzc2VycywgdXNpbmcgZm9yZWFjaCBwYXJhbGxlbCBwcm9jZXNzaW5nIHRha2VzIGFwcHJveGltYXRlbHkgMS8zIHRoZSB0aW1lIChhcm91bmQgMjAgc2Vjb25kcyBwZXIgZW11bGF0b3IpIG9mIGxvb3BpbmcgdGhlIGVtdWxhdG9yIGZpdHRpbmcgZGlyZWN0bHkuIEknZCBob3BlIHRoaXMgd291bGQgc2NhbGUgd2l0aCBwcm9jZXNzb3IgbnVtYmVycyAtIGl0J2xsIGJlIHdvcnRoIHRyeWluZyBvbiBTUElDRS4KCiMgc3lzdGVtLnRpbWUodGVzdGxvb3BfcGFyIDwtIGRpcmVjdF90d29TdGVwX2dsbW5ldF9wYXJhbGxlbChYPVhfbGV2ZWwxLCBZID0gWV9sZXZlbDEpKQoKYGBgCgoKIyMgV3JpdGluZyByb2J1c3QsIHBhcmFsbGVsaXNlZCwgbXVsdGlzdGFydCAgZW11bGF0b3JzCmBgYHtyfQpkaXJlY3RfdHdvU3RlcF9nbG1uZXQgPC0gZnVuY3Rpb24oWCwgWSwgLi4uKXsKICAKICBkIDwtIG5jb2woWSkKICAKICBvdXQgPC0gdmVjdG9yKG1vZGU9J2xpc3QnLCBsZW5ndGg9ZCkKICAKICBmb3IoaSBpbiAxOmQpewogICAgCiAgICB5IDwtIFlbLGldCiAgICAKICAgIGVtIDwtIHR3b1N0ZXBfZ2xtbmV0KFg9WCwgeSA9IHksIC4uLikKICAgIG91dFtpXSA8LSBlbQogCiAgfQogIAogIG91dAp9IAoKCmBgYAoKCiMgRGlyZWN0IHR3b1N0ZXAgZW11bGF0b3IgdXNpbmcgZm9yZWFjaApgYGB7cn0KCmxpYnJhcnkoZG9QYXJhbGxlbCkKcmVnaXN0ZXJEb1BhcmFsbGVsKGNvcmVzID0gZGV0ZWN0Q29yZXMoKSAtIDEpCgpkaXJlY3RfdHdvU3RlcF9nbG1uZXRfcGFyYWxsZWwgPC0gZnVuY3Rpb24oWCwgWSwgLi4uKXsKICAKICBkIDwtIG5jb2woWSkKICAKICBvdXQgPC0gdmVjdG9yKG1vZGU9J2xpc3QnLCBsZW5ndGg9ZCkKICAKICBmb3JlYWNoKGkgPSAxOmQpICVkb3BhciUgewogICAgCiAgICB5IDwtIFlbLGldCiAgICAKICAgIGVtIDwtIHR3b1N0ZXBfZ2xtbmV0KFg9WCwgeSA9IHksIC4uLikKICAgIG91dFtpXSA8LSBlbQogCiAgfQogIAogIG91dAp9IAoKYGBgCgoKCmBgYHtyfQoKIyBJIGFjdHVhbGx5IHdyb3RlIGNvZGUgdG8gZG8gdGhpcyBjcmVhdGVLbUZpdExpc3QsIHdoaWNoIGlzbid0IHBhcmFsbGVsIGF0IHRoZSBtb21lbnQuCiMgTWF5YmUgbWFrZSBpdCBwYXJhbGxlbCBpbiB0aGUgbmV4dCB2ZXJzaW9uPwoKbGlicmFyeShkb1BhcmFsbGVsKQpyZWdpc3RlckRvUGFyYWxsZWwoY29yZXMgPSBkZXRlY3RDb3JlcygpIC0gMSkKCmRpcmVjdF90d29TdGVwX2dsbW5ldF9wYXJhbGxlbCA8LSBmdW5jdGlvbihYLCBZLCAuLi4pewogIAogIGQgPC0gbmNvbChZKQogIGZvcmVhY2goaSA9IDE6ZCkgJWRvcGFyJSB7CiAgICAKICAgIHkgPC0gWVssaV0KICAgIAogICAgZW0gPC0gdHdvU3RlcF9nbG1uZXQoWD1YLCB5ID0geSwgLi4uKQogIH0KfSAKCgoKYGBgCgoKCmBgYHtyfQoKbGlicmFyeShkb1BhcmFsbGVsKQpjb3Jlcz1kZXRlY3RDb3JlcygpCmNsIDwtIG1ha2VDbHVzdGVyKGNvcmVzWzFdLTEpICNub3QgdG8gb3ZlcmxvYWQgeW91ciBjb21wdXRlcgpyZWdpc3RlckRvUGFyYWxsZWwoY2wpCgpmaXRsaXN0X3Rlc3QgPC0gY3JlYXRlS21GaXRMaXN0UGFyYWxsZWwoWCA9IFhfbGV2ZWwxYSwgWSA9ICBZX2NvbnN0X2xldmVsMWFfc2NhbGVkLCBmb3JtdWxhID0gfi4sIG11bHRpc3RhcnQgPSA0KQpzdG9wQ2x1c3RlcihjbCkKCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA5fQoKCnBsb3QoZml0bGlzdF90ZXN0W1s0XV0pCmBgYAoKCmBgYHtyfQoKI3N1bW1hcmlzZUttTG9vIDwtIGZ1bmN0aW9uKGZpdCl7CiAgCiMgIGxvbyA8LSBsZWF2ZU9uZU91dC5rbShmaXQsIHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSkKICAKIyAgbG9vX21lYW4gPC0gbWVhbihsb28kKQogIAogIAojfQoKCgpgYGAKCgoKCgpgYGB7cn0KCiMgc3lzdGVtLnRpbWUodGVzdGxvb3AgPC0gZGlyZWN0X3R3b1N0ZXBfZ2xtbmV0KFg9WF9sZXZlbDEsIFlfbGV2ZWwxKSkKCmBgYAoKCgpgYGB7cn0KIyBUZXN0IHBhcmFsbGVsIHByb2Nlc3NpbmcgYWdhaW5zdCBhIGZvcmVhY2ggcHJvY2Vzc2luZyAoYW5kIG1heWJlIG1jbGFwcGx5PykKCiNzeXN0ZW0udGltZSh0ZXN0bG9vcF9wYXIgPC0gZGlyZWN0X3R3b1N0ZXBfZ2xtbmV0X3BhcmFsbGVsKFg9WF9sZXZlbDEsIFlfbGV2ZWwxKSkKCgoKYGBgCgoKYGBge3J9CmVtTGlzdCA8LSBmdW5jdGlvbihYLCBZKXsKICAjIENyZWF0ZSBhIGxpc3Qgb2Ygb2JqZWN0cyB0byBiZSBlbXVsYXRlZAogICMgWCAgICAgICAgICAgICBkZXNpZ24gbWF0cml4IHdpdGggKG5yb3cpIGluc3RhbmNlcyBvZiAobmNvbCkgaW5wdXRzCiAgIyBZICAgICAgICAgICAgIG1hdHJpeCBvZiBvdXRwdXRzLCB3aXRoIG9uZSByb3cKICAjICAgICAgICAgICAgICAgZm9yIGVhY2ggcm93IG9mIFgKCiAgZCA8LSBuY29sKFkpCiAgZW1fbGlzdCA8LSB2ZWN0b3IobW9kZT0nbGlzdCcsIGxlbmd0aD1kKQoKICBmb3IoaSBpbiAxOmQpewogICAgZW1fb2JqIDwtIE5VTEwKICAgIGVtX29iaiRYIDwtIFgKICAgIGVtX29iaiR5IDwtIFlbLCBpXQogICAgZW1fbGlzdFtbaV1dIDwtIGVtX29iagogIH0KICBlbV9saXN0Cn0KYGBgCgpgYGB7cn0KCgojdGVzdCA8LSBlbWxpc3QoWF9sZXZlbDEsIFlfbGV2ZWwxKQoKCmBgYAoKYGBge3J9CgojbWNsYXBwbHkoWCA9IHRlc3QsIEZVTiA9IGttKQoKCmBgYAoKCgpgYGB7cn0KCiMgZnVuY3Rpb24gZnJvbSBoZGUgZm9yIGRpcmVjdCBwcmVkaWN0aW9uCmRpcmVjdC5wcmVkID0gZnVuY3Rpb24gKGZvcm0sIFgsIFksIFhuZXcsIC4uLil7CiAgIyBEaXJlY3RseSBhcHBsaWVzIGttIGluIHBhcmFsbGVsIHRvIHByZWRpY3QgZWFjaCBjb2x1bW4gb2YgYW4gZW5zZW1ibGUKICBlbnMubGlzdCA9IGVtbGlzdChYID0gWCwgWSA9IFkpCiAga20ubGlzdCA9IG1jbGFwcGx5KGVucy5saXN0LCBGVU4gPSBrbS53cmFwLCBmb3JtID0gZm9ybSkKCiAgcHJlZC5saXN0ID0gbWNsYXBwbHkoa20ubGlzdCwgRlVOID0ga20ucHJlZC53cmFwLCBYbmV3ID0gYXMubWF0cml4KFhuZXcsIG5yb3cgPSAxKSwgdHlwZSA9ICJVSyIpCgogIG91dC5tZWFuID0gc2FwcGx5KHByZWQubGlzdCwgRlVOPWV4dHJhY3QucHJlZG1lYW4pCiAgb3V0LnNkID0gc2FwcGx5KHByZWQubGlzdCwgRlVOPWV4dHJhY3QucHJlZHNkKQogIHJldHVybihsaXN0KG1lYW4gPSBvdXQubWVhbiwgc2QgPSBvdXQuc2QpKQp9CgoKCmBgYAoKCgoKCgoK